// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/compiler/simd-scalar-lowering.h"

#include "src/base/platform/wrappers.h"
#include "src/codegen/machine-type.h"
#include "src/common/globals.h"
#include "src/compiler/diamond.h"
#include "src/compiler/linkage.h"
#include "src/compiler/machine-operator.h"
#include "src/compiler/node-matchers.h"
#include "src/compiler/node-properties.h"
#include "src/compiler/node.h"
#include "src/compiler/wasm-compiler.h"

namespace v8 {
namespace internal {
namespace compiler {

namespace {
static const int kNumLanes64 = 2;
static const int kNumLanes32 = 4;
static const int kNumLanes16 = 8;
static const int kNumLanes8 = 16;
static const int32_t kMask16 = 0xFFFF;
static const int32_t kMask8 = 0xFF;
static const int32_t kShift16 = 16;
static const int32_t kShift8 = 24;
static const int32_t kShiftMask8 = 0x7;
static const int32_t kShiftMask16 = 0xF;
static const int32_t kShiftMask32 = 0x1F;
static const int32_t kShiftMask64 = 0x3F;

// Shift values are taken modulo lane size. This helper calculates the mask
// required for different shift opcodes.
int GetMaskForShift(Node* node) {
  switch (node->opcode()) {
    case IrOpcode::kI8x16Shl:
    case IrOpcode::kI8x16ShrS:
    case IrOpcode::kI8x16ShrU:
      return kShiftMask8;
    case IrOpcode::kI16x8Shl:
    case IrOpcode::kI16x8ShrS:
    case IrOpcode::kI16x8ShrU:
      return kShiftMask16;
    case IrOpcode::kI32x4Shl:
    case IrOpcode::kI32x4ShrS:
    case IrOpcode::kI32x4ShrU:
      return kShiftMask32;
    case IrOpcode::kI64x2Shl:
    case IrOpcode::kI64x2ShrS:
    case IrOpcode::kI64x2ShrU:
      return kShiftMask64;
    default:
      UNIMPLEMENTED();
  }
}
}  // anonymous namespace

SimdScalarLowering::SimdScalarLowering(
    MachineGraph* mcgraph, Signature<MachineRepresentation>* signature)
    : mcgraph_(mcgraph),
      state_(mcgraph->graph(), 3),
      stack_(mcgraph_->zone()),
      replacements_(nullptr),
      signature_(signature),
      placeholder_(graph()->NewNode(common()->Parameter(-2, "placeholder"),
                                    graph()->start())),
      parameter_count_after_lowering_(-1) {
  DCHECK_NOT_NULL(graph());
  DCHECK_NOT_NULL(graph()->end());
  replacements_ = zone()->NewArray<Replacement>(graph()->NodeCount());
  memset(static_cast<void*>(replacements_), 0,
         sizeof(Replacement) * graph()->NodeCount());
}

void SimdScalarLowering::LowerGraph() {
  stack_.push_back({graph()->end(), 0});
  state_.Set(graph()->end(), State::kOnStack);
  replacements_[graph()->end()->id()].type = SimdType::kInt32x4;

  while (!stack_.empty()) {
    NodeState& top = stack_.back();
    if (top.input_index == top.node->InputCount()) {
      // All inputs of top have already been lowered, now lower top.
      stack_.pop_back();
      state_.Set(top.node, State::kVisited);
      LowerNode(top.node);
    } else {
      // Push the next input onto the stack.
      Node* input = top.node->InputAt(top.input_index++);
      if (state_.Get(input) == State::kUnvisited) {
        SetLoweredType(input, top.node);
        if (input->opcode() == IrOpcode::kPhi) {
          // To break cycles with phi nodes we push phis on a separate stack so
          // that they are processed after all other nodes.
          PreparePhiReplacement(input);
          stack_.push_front({input, 0});
        } else if (input->opcode() == IrOpcode::kEffectPhi ||
                   input->opcode() == IrOpcode::kLoop) {
          stack_.push_front({input, 0});
        } else {
          stack_.push_back({input, 0});
        }
        state_.Set(input, State::kOnStack);
      }
    }
  }
}

#define FOREACH_INT64X2_OPCODE(V) \
  V(I64x2Splat)                   \
  V(I64x2ExtractLane)             \
  V(I64x2ReplaceLane)             \
  V(I64x2Neg)                     \
  V(I64x2Shl)                     \
  V(I64x2ShrS)                    \
  V(I64x2ShrU)                    \
  V(I64x2Add)                     \
  V(I64x2Sub)                     \
  V(I64x2Mul)

#define FOREACH_INT32X4_OPCODE(V) \
  V(I32x4Splat)                   \
  V(I32x4ExtractLane)             \
  V(I32x4ReplaceLane)             \
  V(I32x4SConvertF32x4)           \
  V(I32x4UConvertF32x4)           \
  V(I32x4SConvertI16x8Low)        \
  V(I32x4SConvertI16x8High)       \
  V(I32x4Neg)                     \
  V(I32x4Shl)                     \
  V(I32x4ShrS)                    \
  V(I32x4Add)                     \
  V(I32x4AddHoriz)                \
  V(I32x4Sub)                     \
  V(I32x4Mul)                     \
  V(I32x4MinS)                    \
  V(I32x4MaxS)                    \
  V(I32x4ShrU)                    \
  V(I32x4MinU)                    \
  V(I32x4MaxU)                    \
  V(I32x4DotI16x8S)               \
  V(I32x4Eq)                      \
  V(I32x4Ne)                      \
  V(I32x4LtS)                     \
  V(I32x4LtU)                     \
  V(I32x4GtS)                     \
  V(I32x4GtU)                     \
  V(I32x4LeS)                     \
  V(I32x4LeU)                     \
  V(I32x4GeS)                     \
  V(I32x4GeU)                     \
  V(I32x4UConvertI16x8Low)        \
  V(I32x4UConvertI16x8High)       \
  V(I32x4Abs)                     \
  V(S128And)                      \
  V(S128Or)                       \
  V(S128Xor)                      \
  V(S128Not)                      \
  V(S128AndNot)                   \
  V(S128Select)                   \
  V(V32x4AnyTrue)                 \
  V(V32x4AllTrue)                 \
  V(V16x8AnyTrue)                 \
  V(V16x8AllTrue)                 \
  V(V8x16AnyTrue)                 \
  V(V8x16AllTrue)                 \
  V(I32x4BitMask)

#define FOREACH_FLOAT64X2_OPCODE(V) \
  V(F64x2Splat)                     \
  V(F64x2ExtractLane)               \
  V(F64x2ReplaceLane)               \
  V(F64x2Abs)                       \
  V(F64x2Neg)                       \
  V(F64x2Sqrt)                      \
  V(F64x2Add)                       \
  V(F64x2Sub)                       \
  V(F64x2Mul)                       \
  V(F64x2Div)                       \
  V(F64x2Min)                       \
  V(F64x2Max)                       \
  V(F64x2Pmin)                      \
  V(F64x2Pmax)                      \
  V(F64x2Ceil)                      \
  V(F64x2Floor)                     \
  V(F64x2Trunc)                     \
  V(F64x2NearestInt)

#define FOREACH_FLOAT32X4_OPCODE(V) \
  V(F32x4Splat)                     \
  V(F32x4ExtractLane)               \
  V(F32x4ReplaceLane)               \
  V(F32x4SConvertI32x4)             \
  V(F32x4UConvertI32x4)             \
  V(F32x4Abs)                       \
  V(F32x4Neg)                       \
  V(F32x4Sqrt)                      \
  V(F32x4RecipApprox)               \
  V(F32x4RecipSqrtApprox)           \
  V(F32x4Add)                       \
  V(F32x4AddHoriz)                  \
  V(F32x4Sub)                       \
  V(F32x4Mul)                       \
  V(F32x4Div)                       \
  V(F32x4Min)                       \
  V(F32x4Max)                       \
  V(F32x4Pmin)                      \
  V(F32x4Pmax)                      \
  V(F32x4Ceil)                      \
  V(F32x4Floor)                     \
  V(F32x4Trunc)                     \
  V(F32x4NearestInt)

#define FOREACH_FLOAT64x2_TO_INT64x2OPCODE(V) \
  V(F64x2Eq)                                  \
  V(F64x2Ne)                                  \
  V(F64x2Lt)                                  \
  V(F64x2Le)

#define FOREACH_FLOAT32X4_TO_INT32X4OPCODE(V) \
  V(F32x4Eq)                                  \
  V(F32x4Ne)                                  \
  V(F32x4Lt)                                  \
  V(F32x4Le)                                  \
  V(F32x4Gt)                                  \
  V(F32x4Ge)

#define FOREACH_INT16X8_OPCODE(V) \
  V(I16x8Splat)                   \
  V(I16x8ExtractLaneU)            \
  V(I16x8ExtractLaneS)            \
  V(I16x8ReplaceLane)             \
  V(I16x8SConvertI8x16Low)        \
  V(I16x8SConvertI8x16High)       \
  V(I16x8Neg)                     \
  V(I16x8Shl)                     \
  V(I16x8ShrS)                    \
  V(I16x8SConvertI32x4)           \
  V(I16x8Add)                     \
  V(I16x8AddSatS)                 \
  V(I16x8AddHoriz)                \
  V(I16x8Sub)                     \
  V(I16x8SubSatS)                 \
  V(I16x8Mul)                     \
  V(I16x8MinS)                    \
  V(I16x8MaxS)                    \
  V(I16x8UConvertI8x16Low)        \
  V(I16x8UConvertI8x16High)       \
  V(I16x8ShrU)                    \
  V(I16x8UConvertI32x4)           \
  V(I16x8AddSatU)                 \
  V(I16x8SubSatU)                 \
  V(I16x8MinU)                    \
  V(I16x8MaxU)                    \
  V(I16x8Eq)                      \
  V(I16x8Ne)                      \
  V(I16x8LtS)                     \
  V(I16x8LtU)                     \
  V(I16x8GtS)                     \
  V(I16x8GtU)                     \
  V(I16x8LeS)                     \
  V(I16x8LeU)                     \
  V(I16x8GeS)                     \
  V(I16x8GeU)                     \
  V(I16x8RoundingAverageU)        \
  V(I16x8Abs)                     \
  V(I16x8BitMask)

#define FOREACH_INT8X16_OPCODE(V) \
  V(I8x16Splat)                   \
  V(I8x16ExtractLaneU)            \
  V(I8x16ExtractLaneS)            \
  V(I8x16ReplaceLane)             \
  V(I8x16SConvertI16x8)           \
  V(I8x16Neg)                     \
  V(I8x16Shl)                     \
  V(I8x16ShrS)                    \
  V(I8x16Add)                     \
  V(I8x16AddSatS)                 \
  V(I8x16Sub)                     \
  V(I8x16SubSatS)                 \
  V(I8x16Mul)                     \
  V(I8x16MinS)                    \
  V(I8x16MaxS)                    \
  V(I8x16ShrU)                    \
  V(I8x16UConvertI16x8)           \
  V(I8x16AddSatU)                 \
  V(I8x16SubSatU)                 \
  V(I8x16MinU)                    \
  V(I8x16MaxU)                    \
  V(I8x16Eq)                      \
  V(I8x16Ne)                      \
  V(I8x16LtS)                     \
  V(I8x16LtU)                     \
  V(I8x16GtS)                     \
  V(I8x16GtU)                     \
  V(I8x16LeS)                     \
  V(I8x16LeU)                     \
  V(I8x16GeS)                     \
  V(I8x16GeU)                     \
  V(I8x16Swizzle)                 \
  V(I8x16Shuffle)                 \
  V(I8x16RoundingAverageU)        \
  V(I8x16Abs)                     \
  V(I8x16BitMask)

MachineType SimdScalarLowering::MachineTypeFrom(SimdType simdType) {
  switch (simdType) {
    case SimdType::kFloat64x2:
      return MachineType::Float64();
    case SimdType::kFloat32x4:
      return MachineType::Float32();
    case SimdType::kInt64x2:
      return MachineType::Int64();
    case SimdType::kInt32x4:
      return MachineType::Int32();
    case SimdType::kInt16x8:
      return MachineType::Int16();
    case SimdType::kInt8x16:
      return MachineType::Int8();
  }
  return MachineType::None();
}

void SimdScalarLowering::SetLoweredType(Node* node, Node* output) {
  switch (node->opcode()) {
#define CASE_STMT(name) case IrOpcode::k##name:
    FOREACH_FLOAT64X2_OPCODE(CASE_STMT) {
      replacements_[node->id()].type = SimdType::kFloat64x2;
      break;
    }
    FOREACH_INT64X2_OPCODE(CASE_STMT) {
      replacements_[node->id()].type = SimdType::kInt64x2;
      break;
    }
    FOREACH_INT32X4_OPCODE(CASE_STMT)
    case IrOpcode::kReturn:
    case IrOpcode::kParameter:
    case IrOpcode::kPhi:
    case IrOpcode::kCall: {
      replacements_[node->id()].type = SimdType::kInt32x4;
      break;
    }
      FOREACH_FLOAT32X4_OPCODE(CASE_STMT) {
        replacements_[node->id()].type = SimdType::kFloat32x4;
        break;
      }
      FOREACH_FLOAT32X4_TO_INT32X4OPCODE(CASE_STMT) {
        replacements_[node->id()].type = SimdType::kInt32x4;
        break;
      }
      FOREACH_FLOAT64x2_TO_INT64x2OPCODE(CASE_STMT) {
        replacements_[node->id()].type = SimdType::kInt64x2;
        break;
      }
      FOREACH_INT16X8_OPCODE(CASE_STMT) {
        replacements_[node->id()].type = SimdType::kInt16x8;
        break;
      }
      FOREACH_INT8X16_OPCODE(CASE_STMT) {
        replacements_[node->id()].type = SimdType::kInt8x16;
        break;
      }
    case IrOpcode::kLoadTransform: {
      LoadTransformParameters params = LoadTransformParametersOf(node->op());
      switch (params.transformation) {
        case LoadTransformation::kS128Load8Splat:
          replacements_[node->id()].type = SimdType::kInt8x16;
          break;
        case LoadTransformation::kS128Load16Splat:
        case LoadTransformation::kS128Load8x8S:
        case LoadTransformation::kS128Load8x8U:
          replacements_[node->id()].type = SimdType::kInt16x8;
          break;
        case LoadTransformation::kS128Load32Splat:
        case LoadTransformation::kS128Load16x4S:
        case LoadTransformation::kS128Load16x4U:
        case LoadTransformation::kS128Load32Zero:
          replacements_[node->id()].type = SimdType::kInt32x4;
          break;
        case LoadTransformation::kS128Load64Splat:
        case LoadTransformation::kS128Load32x2S:
        case LoadTransformation::kS128Load32x2U:
        case LoadTransformation::kS128Load64Zero:
          replacements_[node->id()].type = SimdType::kInt64x2;
          break;
        default:
          UNIMPLEMENTED();
      }
      break;
    }
    default: {
      switch (output->opcode()) {
        case IrOpcode::kF32x4SConvertI32x4:
        case IrOpcode::kF32x4UConvertI32x4:
        case IrOpcode::kI16x8SConvertI32x4:
        case IrOpcode::kI16x8UConvertI32x4: {
          replacements_[node->id()].type = SimdType::kInt32x4;
          break;
        }
        case IrOpcode::kI8x16SConvertI16x8:
        case IrOpcode::kI8x16UConvertI16x8:
        case IrOpcode::kI32x4SConvertI16x8Low:
        case IrOpcode::kI32x4SConvertI16x8High:
        case IrOpcode::kI32x4UConvertI16x8Low:
        case IrOpcode::kI32x4UConvertI16x8High: {
          replacements_[node->id()].type = SimdType::kInt16x8;
          break;
        }
        case IrOpcode::kI16x8SConvertI8x16Low:
        case IrOpcode::kI16x8SConvertI8x16High:
        case IrOpcode::kI16x8UConvertI8x16Low:
        case IrOpcode::kI16x8UConvertI8x16High: {
          replacements_[node->id()].type = SimdType::kInt8x16;
          break;
        }
          FOREACH_FLOAT32X4_TO_INT32X4OPCODE(CASE_STMT)
        case IrOpcode::kI32x4SConvertF32x4:
        case IrOpcode::kI32x4UConvertF32x4: {
          replacements_[node->id()].type = SimdType::kFloat32x4;
          break;
        }
        case IrOpcode::kS128Select: {
          replacements_[node->id()].type = SimdType::kInt32x4;
          break;
        }
        default: {
          replacements_[node->id()].type = replacements_[output->id()].type;
        }
      }
    }
#undef CASE_STMT
  }
}

static int GetParameterIndexAfterLoweringSimd128(
    Signature<MachineRepresentation>* signature, int old_index) {
  // In function calls, the simd128 types are passed as 4 Int32 types. The
  // parameters are typecast to the types as needed for various operations.
  int result = old_index;
  for (int i = 0; i < old_index; ++i) {
    if (signature->GetParam(i) == MachineRepresentation::kSimd128) {
      result += 3;
    }
  }
  return result;
}

int SimdScalarLowering::GetParameterCountAfterLowering() {
  if (parameter_count_after_lowering_ == -1) {
    // GetParameterIndexAfterLoweringSimd128(parameter_count) returns the
    // parameter count after lowering.
    parameter_count_after_lowering_ = GetParameterIndexAfterLoweringSimd128(
        signature(), static_cast<int>(signature()->parameter_count()));
  }
  return parameter_count_after_lowering_;
}

static int GetReturnCountAfterLoweringSimd128(
    Signature<MachineRepresentation>* signature) {
  int result = static_cast<int>(signature->return_count());
  for (int i = 0; i < static_cast<int>(signature->return_count()); ++i) {
    if (signature->GetReturn(i) == MachineRepresentation::kSimd128) {
      result += 3;
    }
  }
  return result;
}

int GetReturnIndexAfterLowering(const CallDescriptor* call_descriptor,
                                int old_index) {
  int result = old_index;
  for (int i = 0; i < old_index; ++i) {
    if (call_descriptor->GetReturnType(i).representation() ==
        MachineRepresentation::kSimd128) {
      result += kNumLanes32 - 1;
    }
  }
  return result;
}

static int GetReturnCountAfterLoweringSimd128(
    const CallDescriptor* call_descriptor) {
  return GetReturnIndexAfterLowering(
      call_descriptor, static_cast<int>(call_descriptor->ReturnCount()));
}

int SimdScalarLowering::NumLanes(SimdType type) {
  int num_lanes = 0;
  if (type == SimdType::kFloat64x2 || type == SimdType::kInt64x2) {
    num_lanes = kNumLanes64;
  } else if (type == SimdType::kFloat32x4 || type == SimdType::kInt32x4) {
    num_lanes = kNumLanes32;
  } else if (type == SimdType::kInt16x8) {
    num_lanes = kNumLanes16;
  } else if (type == SimdType::kInt8x16) {
    num_lanes = kNumLanes8;
  } else {
    UNREACHABLE();
  }
  return num_lanes;
}

constexpr int SimdScalarLowering::kLaneOffsets[];

void SimdScalarLowering::GetIndexNodes(Node* index, Node** new_indices,
                                       SimdType type) {
  int num_lanes = NumLanes(type);
  int lane_width = kSimd128Size / num_lanes;
  int laneIndex = kLaneOffsets[0] / lane_width;
  new_indices[laneIndex] = index;
  for (int i = 1; i < num_lanes; ++i) {
    laneIndex = kLaneOffsets[i * lane_width] / lane_width;
    new_indices[laneIndex] = graph()->NewNode(
        machine()->Int32Add(), index,
        graph()->NewNode(
            common()->Int32Constant(static_cast<int>(i) * lane_width)));
  }
}

void SimdScalarLowering::LowerLoadOp(Node* node, SimdType type) {
  MachineRepresentation rep = LoadRepresentationOf(node->op()).representation();
  const Operator* load_op;
  switch (node->opcode()) {
    case IrOpcode::kLoad:
      load_op = machine()->Load(MachineTypeFrom(type));
      break;
    case IrOpcode::kUnalignedLoad:
      load_op = machine()->UnalignedLoad(MachineTypeFrom(type));
      break;
    case IrOpcode::kProtectedLoad:
      load_op = machine()->ProtectedLoad(MachineTypeFrom(type));
      break;
    default:
      UNREACHABLE();
  }
  if (rep == MachineRepresentation::kSimd128) {
    Node* base = node->InputAt(0);
    Node* index = node->InputAt(1);
    int num_lanes = NumLanes(type);
    Node** indices = zone()->NewArray<Node*>(num_lanes);
    GetIndexNodes(index, indices, type);
    Node** rep_nodes = zone()->NewArray<Node*>(num_lanes);
    rep_nodes[0] = node;
    rep_nodes[0]->ReplaceInput(1, indices[0]);
    NodeProperties::ChangeOp(rep_nodes[0], load_op);
    if (node->InputCount() > 2) {
      DCHECK_LT(3, node->InputCount());
      Node* effect_input = node->InputAt(2);
      Node* control_input = node->InputAt(3);
      for (int i = num_lanes - 1; i > 0; --i) {
        rep_nodes[i] = graph()->NewNode(load_op, base, indices[i], effect_input,
                                        control_input);
        effect_input = rep_nodes[i];
      }
      rep_nodes[0]->ReplaceInput(2, rep_nodes[1]);
    } else {
      for (int i = 1; i < num_lanes; ++i) {
        rep_nodes[i] = graph()->NewNode(load_op, base, indices[i]);
      }
    }
    ReplaceNode(node, rep_nodes, num_lanes);
  } else {
    DefaultLowering(node);
  }
}

void SimdScalarLowering::LowerLoadTransformOp(Node* node, SimdType type) {
  LoadTransformParameters params = LoadTransformParametersOf(node->op());
  MachineType load_rep = MachineType::None();
  SimdType load_type = type;

  // Load extends have a different machine type for loading.
  switch (params.transformation) {
    case LoadTransformation::kS128Load8x8S:
      load_rep = MachineType::Int8();
      load_type = SimdType::kInt8x16;
      break;
    case LoadTransformation::kS128Load8x8U:
      load_rep = MachineType::Uint8();
      load_type = SimdType::kInt8x16;
      break;
    case LoadTransformation::kS128Load16x4S:
      load_rep = MachineType::Int16();
      load_type = SimdType::kInt16x8;
      break;
    case LoadTransformation::kS128Load16x4U:
      load_rep = MachineType::Uint16();
      load_type = SimdType::kInt16x8;
      break;
    case LoadTransformation::kS128Load32x2S:
      load_rep = MachineType::Int32();
      load_type = SimdType::kInt32x4;
      break;
    case LoadTransformation::kS128Load32x2U:
      load_rep = MachineType::Uint32();
      load_type = SimdType::kInt32x4;
      break;
    case LoadTransformation::kS128Load8Splat:
    case LoadTransformation::kS128Load16Splat:
    case LoadTransformation::kS128Load32Splat:
    case LoadTransformation::kS128Load64Splat:
    case LoadTransformation::kS128Load32Zero:
    case LoadTransformation::kS128Load64Zero:
      load_rep = MachineTypeFrom(type);
      break;
    default:
      UNREACHABLE();
  }

  DCHECK_NE(load_rep, MachineType::None());

  const Operator* load_op;
  switch (params.kind) {
    case MemoryAccessKind::kNormal:
      load_op = machine()->Load(load_rep);
      break;
    case MemoryAccessKind::kUnaligned:
      load_op = machine()->UnalignedLoad(load_rep);
      break;
    case MemoryAccessKind::kProtected:
      load_op = machine()->ProtectedLoad(load_rep);
      break;
  }

  Node* base = node->InputAt(0);
  Node* index = node->InputAt(1);
  int num_lanes = NumLanes(type);
  Node** reps = zone()->NewArray<Node*>(num_lanes);
  Node* effect_input = node->InputAt(2);
  Node* control_input = node->InputAt(3);

  // This node is also used as effect input into other nodes, so we need to
  // change this node in place.
  reps[0] = node;
  NodeProperties::ChangeOp(reps[0], load_op);

  if (type != load_type) {
    // We load a smaller lane size, then extend to a larger lane size. So use
    // the smaller lane size to calculte the index nodes for loads, but only
    // actually load half of those lanes.
    Node** indices = zone()->NewArray<Node*>(num_lanes * 2);
    GetIndexNodes(index, indices, load_type);

    reps[0]->ReplaceInput(1, indices[0]);

    for (int i = num_lanes - 1; i > 0; --i) {
      reps[i] = graph()->NewNode(load_op, base, indices[i], effect_input,
                                 control_input);
      effect_input = reps[i];
    }
  } else {
    if (params.transformation == LoadTransformation::kS128Load32Zero) {
      for (int i = num_lanes - 1; i > 0; --i) {
        reps[i] = mcgraph_->Int32Constant(0);
      }
    } else if (params.transformation == LoadTransformation::kS128Load64Zero) {
      for (int i = num_lanes - 1; i > 0; --i) {
        reps[i] = mcgraph_->Int64Constant(0);
      }
    } else {
      // Load splat, load from the same index for every lane.
      for (int i = num_lanes - 1; i > 0; --i) {
        reps[i] =
            graph()->NewNode(load_op, base, index, effect_input, control_input);
        effect_input = reps[i];
      }
    }
  }

  // Update the effect input, completing the effect chain, but only if there is
  // an effect output (LoadZero does not have an effect output, it is zero).
  if (reps[1]->op()->EffectOutputCount() > 0) {
    reps[0]->ReplaceInput(2, reps[1]);
  }

  // Special case, the load nodes need to be sign extended, and we do it here so
  // the loop above can connect all the effect edges correctly.
  if (params.transformation == LoadTransformation::kS128Load32x2S) {
    for (int i = 0; i < num_lanes; ++i) {
      reps[i] = graph()->NewNode(machine()->ChangeInt32ToInt64(), reps[i]);
    }
  } else if (params.transformation == LoadTransformation::kS128Load32x2U) {
    for (int i = 0; i < num_lanes; ++i) {
      reps[i] = graph()->NewNode(machine()->ChangeUint32ToUint64(), reps[i]);
    }
  }

  ReplaceNode(node, reps, num_lanes);
}

void SimdScalarLowering::LowerStoreOp(Node* node) {
  // For store operation, use replacement type of its input instead of the
  // one of its effected node.
  DCHECK_LT(2, node->InputCount());
  SimdType rep_type = ReplacementType(node->InputAt(2));
  replacements_[node->id()].type = rep_type;
  const Operator* store_op;
  MachineRepresentation rep;
  switch (node->opcode()) {
    case IrOpcode::kStore: {
      rep = StoreRepresentationOf(node->op()).representation();
      WriteBarrierKind write_barrier_kind =
          StoreRepresentationOf(node->op()).write_barrier_kind();
      store_op = machine()->Store(StoreRepresentation(
          MachineTypeFrom(rep_type).representation(), write_barrier_kind));
      break;
    }
    case IrOpcode::kUnalignedStore: {
      rep = UnalignedStoreRepresentationOf(node->op());
      store_op =
          machine()->UnalignedStore(MachineTypeFrom(rep_type).representation());
      break;
    }
    case IrOpcode::kProtectedStore: {
      rep = StoreRepresentationOf(node->op()).representation();
      store_op =
          machine()->ProtectedStore(MachineTypeFrom(rep_type).representation());
      break;
    }
    default:
      UNREACHABLE();
  }
  if (rep == MachineRepresentation::kSimd128) {
    Node* base = node->InputAt(0);
    Node* index = node->InputAt(1);
    int num_lanes = NumLanes(rep_type);
    Node** indices = zone()->NewArray<Node*>(num_lanes);
    GetIndexNodes(index, indices, rep_type);
    Node* value = node->InputAt(2);
    DCHECK(HasReplacement(1, value));
    Node** rep_nodes = zone()->NewArray<Node*>(num_lanes);
    rep_nodes[0] = node;
    Node** rep_inputs = GetReplacementsWithType(value, rep_type);
    rep_nodes[0]->ReplaceInput(2, rep_inputs[0]);
    rep_nodes[0]->ReplaceInput(1, indices[0]);
    NodeProperties::ChangeOp(node, store_op);
    if (node->InputCount() > 3) {
      DCHECK_LT(4, node->InputCount());
      Node* effect_input = node->InputAt(3);
      Node* control_input = node->InputAt(4);
      for (int i = num_lanes - 1; i > 0; --i) {
        rep_nodes[i] =
            graph()->NewNode(store_op, base, indices[i], rep_inputs[i],
                             effect_input, control_input);
        effect_input = rep_nodes[i];
      }
      rep_nodes[0]->ReplaceInput(3, rep_nodes[1]);
    } else {
      for (int i = 1; i < num_lanes; ++i) {
        rep_nodes[i] =
            graph()->NewNode(store_op, base, indices[i], rep_inputs[i]);
      }
    }
    ReplaceNode(node, rep_nodes, num_lanes);
  } else {
    DefaultLowering(node);
  }
}

void SimdScalarLowering::LowerBinaryOp(Node* node, SimdType input_rep_type,
                                       const Operator* op,
                                       bool not_horizontal) {
  DCHECK_EQ(2, node->InputCount());
  Node** rep_left = GetReplacementsWithType(node->InputAt(0), input_rep_type);
  Node** rep_right = GetReplacementsWithType(node->InputAt(1), input_rep_type);
  int num_lanes = NumLanes(input_rep_type);
  Node** rep_node = zone()->NewArray<Node*>(num_lanes);
  if (not_horizontal) {
    for (int i = 0; i < num_lanes; ++i) {
      rep_node[i] = graph()->NewNode(op, rep_left[i], rep_right[i]);
    }
  } else {
    for (int i = 0; i < num_lanes / 2; ++i) {
      rep_node[i] = graph()->NewNode(op, rep_left[i * 2], rep_left[i * 2 + 1]);
      rep_node[i + num_lanes / 2] =
          graph()->NewNode(op, rep_right[i * 2], rep_right[i * 2 + 1]);
    }
  }
  ReplaceNode(node, rep_node, num_lanes);
}

void SimdScalarLowering::LowerCompareOp(Node* node, SimdType input_rep_type,
                                        const Operator* op,
                                        bool invert_inputs) {
  DCHECK_EQ(2, node->InputCount());
  Node** rep_left = GetReplacementsWithType(node->InputAt(0), input_rep_type);
  Node** rep_right = GetReplacementsWithType(node->InputAt(1), input_rep_type);
  int num_lanes = NumLanes(input_rep_type);
  Node** rep_node = zone()->NewArray<Node*>(num_lanes);
  for (int i = 0; i < num_lanes; ++i) {
    Node* cmp_result = nullptr;
    if (invert_inputs) {
      cmp_result = graph()->NewNode(op, rep_right[i], rep_left[i]);
    } else {
      cmp_result = graph()->NewNode(op, rep_left[i], rep_right[i]);
    }
    Diamond d_cmp(graph(), common(), cmp_result);
    rep_node[i] = ConstructPhiForComparison(d_cmp, input_rep_type, -1, 0);
  }
  ReplaceNode(node, rep_node, num_lanes);
}

Node* SimdScalarLowering::FixUpperBits(Node* input, int32_t shift) {
  return graph()->NewNode(machine()->Word32Sar(),
                          graph()->NewNode(machine()->Word32Shl(), input,
                                           mcgraph_->Int32Constant(shift)),
                          mcgraph_->Int32Constant(shift));
}

void SimdScalarLowering::LowerBinaryOpForSmallInt(Node* node,
                                                  SimdType input_rep_type,
                                                  const Operator* op,
                                                  bool not_horizontal) {
  DCHECK_EQ(2, node->InputCount());
  DCHECK(input_rep_type == SimdType::kInt16x8 ||
         input_rep_type == SimdType::kInt8x16);
  Node** rep_left = GetReplacementsWithType(node->InputAt(0), input_rep_type);
  Node** rep_right = GetReplacementsWithType(node->InputAt(1), input_rep_type);
  int num_lanes = NumLanes(input_rep_type);
  Node** rep_node = zone()->NewArray<Node*>(num_lanes);
  int32_t shift_val =
      (input_rep_type == SimdType::kInt16x8) ? kShift16 : kShift8;
  if (not_horizontal) {
    for (int i = 0; i < num_lanes; ++i) {
      rep_node[i] = FixUpperBits(
          graph()->NewNode(op, rep_left[i], rep_right[i]), shift_val);
    }
  } else {
    for (int i = 0; i < num_lanes / 2; ++i) {
      rep_node[i] = FixUpperBits(
          graph()->NewNode(op, rep_left[i * 2], rep_left[i * 2 + 1]),
          shift_val);
      rep_node[i + num_lanes / 2] = FixUpperBits(
          graph()->NewNode(op, rep_right[i * 2], rep_right[i * 2 + 1]),
          shift_val);
    }
  }
  ReplaceNode(node, rep_node, num_lanes);
}

Node* SimdScalarLowering::Mask(Node* input, int32_t mask) {
  return graph()->NewNode(machine()->Word32And(), input,
                          mcgraph_->Int32Constant(mask));
}

void SimdScalarLowering::LowerSaturateBinaryOp(Node* node,
                                               SimdType input_rep_type,
                                               const Operator* op,
                                               bool is_signed) {
  DCHECK_EQ(2, node->InputCount());
  DCHECK(input_rep_type == SimdType::kInt16x8 ||
         input_rep_type == SimdType::kInt8x16);
  Node** rep_left = GetReplacementsWithType(node->InputAt(0), input_rep_type);
  Node** rep_right = GetReplacementsWithType(node->InputAt(1), input_rep_type);
  int32_t min = 0;
  int32_t max = 0;
  int32_t mask = 0;
  int32_t shift_val = 0;
  MachineRepresentation phi_rep;
  if (input_rep_type == SimdType::kInt16x8) {
    if (is_signed) {
      min = std::numeric_limits<int16_t>::min();
      max = std::numeric_limits<int16_t>::max();
    } else {
      min = std::numeric_limits<uint16_t>::min();
      max = std::numeric_limits<uint16_t>::max();
    }
    mask = kMask16;
    shift_val = kShift16;
    phi_rep = MachineRepresentation::kWord16;
  } else {
    if (is_signed) {
      min = std::numeric_limits<int8_t>::min();
      max = std::numeric_limits<int8_t>::max();
    } else {
      min = std::numeric_limits<uint8_t>::min();
      max = std::numeric_limits<uint8_t>::max();
    }
    mask = kMask8;
    shift_val = kShift8;
    phi_rep = MachineRepresentation::kWord8;
  }
  int num_lanes = NumLanes(input_rep_type);
  Node** rep_node = zone()->NewArray<Node*>(num_lanes);
  for (int i = 0; i < num_lanes; ++i) {
    Node* op_result = nullptr;
    Node* left = is_signed ? rep_left[i] : Mask(rep_left[i], mask);
    Node* right = is_signed ? rep_right[i] : Mask(rep_right[i], mask);
    op_result = graph()->NewNode(op, left, right);
    Diamond d_min(graph(), common(),
                  graph()->NewNode(machine()->Int32LessThan(), op_result,
                                   mcgraph_->Int32Constant(min)));
    rep_node[i] = d_min.Phi(phi_rep, mcgraph_->Int32Constant(min), op_result);
    Diamond d_max(graph(), common(),
                  graph()->NewNode(machine()->Int32LessThan(),
                                   mcgraph_->Int32Constant(max), rep_node[i]));
    rep_node[i] = d_max.Phi(phi_rep, mcgraph_->Int32Constant(max), rep_node[i]);
    rep_node[i] =
        is_signed ? rep_node[i] : FixUpperBits(rep_node[i], shift_val);
  }
  ReplaceNode(node, rep_node, num_lanes);
}

void SimdScalarLowering::LowerUnaryOp(Node* node, SimdType input_rep_type,
                                      const Operator* op) {
  DCHECK_EQ(1, node->InputCount());
  Node** rep = GetReplacementsWithType(node->InputAt(0), input_rep_type);
  int num_lanes = NumLanes(input_rep_type);
  Node** rep_node = zone()->NewArray<Node*>(num_lanes);
  for (int i = 0; i < num_lanes; ++i) {
    rep_node[i] = graph()->NewNode(op, rep[i]);
  }
  ReplaceNode(node, rep_node, num_lanes);
}

void SimdScalarLowering::LowerIntMinMax(Node* node, const Operator* op,
                                        bool is_max, SimdType type) {
  DCHECK_EQ(2, node->InputCount());
  Node** rep_left = GetReplacementsWithType(node->InputAt(0), type);
  Node** rep_right = GetReplacementsWithType(node->InputAt(1), type);
  int num_lanes = NumLanes(type);
  Node** rep_node = zone()->NewArray<Node*>(num_lanes);
  MachineRepresentation rep = MachineRepresentation::kNone;
  if (type == SimdType::kInt32x4) {
    rep = MachineRepresentation::kWord32;
  } else if (type == SimdType::kInt16x8) {
    rep = MachineRepresentation::kWord16;
  } else if (type == SimdType::kInt8x16) {
    rep = MachineRepresentation::kWord8;
  } else {
    UNREACHABLE();
  }
  for (int i = 0; i < num_lanes; ++i) {
    Diamond d(graph(), common(),
              graph()->NewNode(op, rep_left[i], rep_right[i]));
    if (is_max) {
      rep_node[i] = d.Phi(rep, rep_right[i], rep_left[i]);
    } else {
      rep_node[i] = d.Phi(rep, rep_left[i], rep_right[i]);
    }
  }
  ReplaceNode(node, rep_node, num_lanes);
}

Node* SimdScalarLowering::BuildF64Trunc(Node* input) {
  if (machine()->Float64RoundTruncate().IsSupported()) {
    return graph()->NewNode(machine()->Float64RoundTruncate().op(), input);
  } else {
    ExternalReference ref = ExternalReference::wasm_f64_trunc();
    Node* stack_slot =
        graph()->NewNode(machine()->StackSlot(MachineRepresentation::kFloat64));
    const Operator* store_op = machine()->Store(
        StoreRepresentation(MachineRepresentation::kFloat64, kNoWriteBarrier));
    Node* effect =
        graph()->NewNode(store_op, stack_slot, mcgraph_->Int32Constant(0),
                         input, graph()->start(), graph()->start());
    Node* function = graph()->NewNode(common()->ExternalConstant(ref));
    Node** args = zone()->NewArray<Node*>(4);
    args[0] = function;
    args[1] = stack_slot;
    args[2] = effect;
    args[3] = graph()->start();
    Signature<MachineType>::Builder sig_builder(zone(), 0, 1);
    sig_builder.AddParam(MachineType::Pointer());
    auto call_descriptor =
        Linkage::GetSimplifiedCDescriptor(zone(), sig_builder.Build());
    Node* call = graph()->NewNode(common()->Call(call_descriptor), 4, args);
    return graph()->NewNode(machine()->Load(LoadRepresentation::Float64()),
                            stack_slot, mcgraph_->Int32Constant(0), call,
                            graph()->start());
  }
}

void SimdScalarLowering::LowerConvertFromFloat(Node* node, bool is_signed) {
  DCHECK_EQ(1, node->InputCount());
  Node** rep = GetReplacementsWithType(node->InputAt(0), SimdType::kFloat32x4);
  Node* rep_node[kNumLanes32];
  Node* double_zero = graph()->NewNode(common()->Float64Constant(0.0));
  Node* min = graph()->NewNode(
      common()->Float64Constant(static_cast<double>(is_signed ? kMinInt : 0)));
  Node* max = graph()->NewNode(common()->Float64Constant(
      static_cast<double>(is_signed ? kMaxInt : 0xFFFFFFFFu)));
  for (int i = 0; i < kNumLanes32; ++i) {
    Node* double_rep =
        graph()->NewNode(machine()->ChangeFloat32ToFloat64(), rep[i]);
    Diamond nan_d(
        graph(), common(),
        graph()->NewNode(machine()->Float64Equal(), double_rep, double_rep));
    Node* temp =
        nan_d.Phi(MachineRepresentation::kFloat64, double_rep, double_zero);
    Diamond min_d(graph(), common(),
                  graph()->NewNode(machine()->Float64LessThan(), temp, min));
    temp = min_d.Phi(MachineRepresentation::kFloat64, min, temp);
    Diamond max_d(graph(), common(),
                  graph()->NewNode(machine()->Float64LessThan(), max, temp));
    temp = max_d.Phi(MachineRepresentation::kFloat64, max, temp);
    Node* trunc = BuildF64Trunc(temp);
    if (is_signed) {
      rep_node[i] = graph()->NewNode(machine()->ChangeFloat64ToInt32(), trunc);
    } else {
      rep_node[i] =
          graph()->NewNode(machine()->TruncateFloat64ToUint32(), trunc);
    }
  }
  ReplaceNode(node, rep_node, kNumLanes32);
}

void SimdScalarLowering::LowerConvertFromInt(Node* node,
                                             SimdType input_rep_type,
                                             SimdType output_rep_type,
                                             bool is_signed, int start_index) {
  DCHECK_EQ(1, node->InputCount());
  Node** rep = GetReplacementsWithType(node->InputAt(0), input_rep_type);

  int32_t mask = 0;
  if (input_rep_type == SimdType::kInt16x8) {
    DCHECK_EQ(output_rep_type, SimdType::kInt32x4);
    mask = kMask16;
  } else {
    DCHECK_EQ(output_rep_type, SimdType::kInt16x8);
    DCHECK_EQ(input_rep_type, SimdType::kInt8x16);
    mask = kMask8;
  }

  int num_lanes = NumLanes(output_rep_type);
  Node** rep_node = zone()->NewArray<Node*>(num_lanes);
  for (int i = 0; i < num_lanes; ++i) {
    rep_node[i] =
        is_signed ? rep[i + start_index] : Mask(rep[i + start_index], mask);
  }

  ReplaceNode(node, rep_node, num_lanes);
}

void SimdScalarLowering::LowerPack(Node* node, SimdType input_rep_type,
                                   SimdType output_rep_type, bool is_signed) {
  DCHECK_EQ(2, node->InputCount());
  Node** rep_left = GetReplacementsWithType(node->InputAt(0), input_rep_type);
  Node** rep_right = GetReplacementsWithType(node->InputAt(1), input_rep_type);
  const Operator* less_op = machine()->Int32LessThan();
  Node* min = nullptr;
  Node* max = nullptr;
  const Operator* sign_extend;
  MachineRepresentation phi_rep;
  if (output_rep_type == SimdType::kInt16x8) {
    sign_extend = machine()->SignExtendWord16ToInt32();
    DCHECK(input_rep_type == SimdType::kInt32x4);
    if (is_signed) {
      min = mcgraph_->Int32Constant(std::numeric_limits<int16_t>::min());
      max = mcgraph_->Int32Constant(std::numeric_limits<int16_t>::max());
    } else {
      min = mcgraph_->Uint32Constant(std::numeric_limits<uint16_t>::min());
      max = mcgraph_->Uint32Constant(std::numeric_limits<uint16_t>::max());
    }
    phi_rep = MachineRepresentation::kWord16;
  } else {
    sign_extend = machine()->SignExtendWord8ToInt32();
    DCHECK(output_rep_type == SimdType::kInt8x16 &&
           input_rep_type == SimdType::kInt16x8);
    if (is_signed) {
      min = mcgraph_->Int32Constant(std::numeric_limits<int8_t>::min());
      max = mcgraph_->Int32Constant(std::numeric_limits<int8_t>::max());
    } else {
      min = mcgraph_->Uint32Constant(std::numeric_limits<uint8_t>::min());
      max = mcgraph_->Uint32Constant(std::numeric_limits<uint8_t>::max());
    }
    phi_rep = MachineRepresentation::kWord8;
  }
  int num_lanes = NumLanes(output_rep_type);
  Node** rep_node = zone()->NewArray<Node*>(num_lanes);
  for (int i = 0; i < num_lanes; ++i) {
    Node* input = nullptr;
    if (i < num_lanes / 2)
      input = rep_left[i];
    else
      input = rep_right[i - num_lanes / 2];
    Diamond d_min(graph(), common(), graph()->NewNode(less_op, input, min));
    input = d_min.Phi(phi_rep, min, input);
    Diamond d_max(graph(), common(), graph()->NewNode(less_op, max, input));
    // We keep nodes in sign-extended form. E.g. for uint8_t, we need to
    // compare with 0x000000ff (saturated narrowing), but the result of
    // conversion should be 0xffffffff to work well with the rest of lowering.
    rep_node[i] = graph()->NewNode(sign_extend, d_max.Phi(phi_rep, max, input));
  }
  ReplaceNode(node, rep_node, num_lanes);
}

void SimdScalarLowering::LowerShiftOp(Node* node, SimdType type) {
  DCHECK_EQ(2, node->InputCount());

  // The shift node, if it has a replacement, should be a single scalar.
  DCHECK_GE(1, ReplacementCount(node->InputAt(1)));
  Node* val = (HasReplacement(0, node->InputAt(1)))
                  ? GetReplacements(node->InputAt(1))[0]
                  : node->InputAt(1);

  Node* shift_node = Mask(val, GetMaskForShift(node));
  Node** rep = GetReplacementsWithType(node->InputAt(0), type);
  int num_lanes = NumLanes(type);
  Node** rep_node = zone()->NewArray<Node*>(num_lanes);
  for (int i = 0; i < num_lanes; ++i) {
    rep_node[i] = rep[i];
    switch (node->opcode()) {
      case IrOpcode::kI8x16ShrU:
        rep_node[i] = Mask(rep_node[i], kMask8);
        rep_node[i] =
            graph()->NewNode(machine()->Word32Shr(), rep_node[i], shift_node);
        break;
      case IrOpcode::kI16x8ShrU:
        rep_node[i] = Mask(rep_node[i], kMask16);
        V8_FALLTHROUGH;
      case IrOpcode::kI32x4ShrU:
        rep_node[i] =
            graph()->NewNode(machine()->Word32Shr(), rep_node[i], shift_node);
        break;
      case IrOpcode::kI64x2ShrU:
        rep_node[i] =
            graph()->NewNode(machine()->Word64Shr(), rep_node[i], shift_node);
        break;
      case IrOpcode::kI64x2Shl:
        rep_node[i] =
            graph()->NewNode(machine()->Word64Shl(), rep_node[i], shift_node);
        break;
      case IrOpcode::kI32x4Shl:
        rep_node[i] =
            graph()->NewNode(machine()->Word32Shl(), rep_node[i], shift_node);
        break;
      case IrOpcode::kI16x8Shl:
        rep_node[i] =
            graph()->NewNode(machine()->Word32Shl(), rep_node[i], shift_node);
        rep_node[i] = FixUpperBits(rep_node[i], kShift16);
        break;
      case IrOpcode::kI8x16Shl:
        rep_node[i] =
            graph()->NewNode(machine()->Word32Shl(), rep_node[i], shift_node);
        rep_node[i] = FixUpperBits(rep_node[i], kShift8);
        break;
      case IrOpcode::kI64x2ShrS:
        rep_node[i] =
            graph()->NewNode(machine()->Word64Sar(), rep_node[i], shift_node);
        break;
      case IrOpcode::kI32x4ShrS:
      case IrOpcode::kI16x8ShrS:
      case IrOpcode::kI8x16ShrS:
        rep_node[i] =
            graph()->NewNode(machine()->Word32Sar(), rep_node[i], shift_node);
        break;
      default:
        UNREACHABLE();
    }
  }
  ReplaceNode(node, rep_node, num_lanes);
}

Node* SimdScalarLowering::ConstructPhiForComparison(Diamond d,
                                                    SimdType rep_type,
                                                    int true_value,
                                                    int false_value) {
  // Close the given Diamond d using a Phi node, taking care of constructing the
  // right kind of constants (Int32 or Int64) based on rep_type.
  if (rep_type == SimdType::kFloat64x2) {
    MachineRepresentation rep = MachineRepresentation::kWord64;
    return d.Phi(rep, mcgraph_->Int64Constant(true_value),
                 mcgraph_->Int64Constant(false_value));
  } else {
    MachineRepresentation rep =
        (rep_type == SimdType::kFloat32x4)
            ? MachineRepresentation::kWord32
            : MachineTypeFrom(rep_type).representation();
    return d.Phi(rep, mcgraph_->Int32Constant(true_value),
                 mcgraph_->Int32Constant(false_value));
  }
}

void SimdScalarLowering::LowerNotEqual(Node* node, SimdType input_rep_type,
                                       const Operator* op) {
  DCHECK_EQ(2, node->InputCount());
  Node** rep_left = GetReplacementsWithType(node->InputAt(0), input_rep_type);
  Node** rep_right = GetReplacementsWithType(node->InputAt(1), input_rep_type);
  int num_lanes = NumLanes(input_rep_type);
  Node** rep_node = zone()->NewArray<Node*>(num_lanes);
  for (int i = 0; i < num_lanes; ++i) {
    Diamond d(graph(), common(),
              graph()->NewNode(op, rep_left[i], rep_right[i]));
    rep_node[i] = ConstructPhiForComparison(d, input_rep_type, 0, -1);
  }
  ReplaceNode(node, rep_node, num_lanes);
}

void SimdScalarLowering::LowerBitMaskOp(Node* node, SimdType rep_type,
                                        int msb_index) {
  Node** reps = GetReplacementsWithType(node->InputAt(0), rep_type);
  int num_lanes = NumLanes(rep_type);
  Node** rep_node = zone()->NewArray<Node*>(1);
  Node* result = mcgraph_->Int32Constant(0);
  uint32_t mask = 1 << msb_index;

  for (int i = 0; i < num_lanes; ++i) {
    // Lane i should end up at bit i in the final result.
    // +-----------------------------------------------------------------+
    // |       | msb_index |   (i < msb_index)    |    (i > msb_index)   |
    // +-------+-----------+----------------------+----------------------+
    // | i8x16 |     7     | msb >> (msb_index-i) | msb << (i-msb_index) |
    // | i16x8 |    15     | msb >> (msb_index-i) |         n/a          |
    // | i32x4 |    31     | msb >> (msb_index-i) |         n/a          |
    // +-------+-----------+----------------------+----------------------+
    Node* msb = Mask(reps[i], mask);

    if (i < msb_index) {
      int shift = msb_index - i;
      Node* shifted = graph()->NewNode(machine()->Word32Shr(), msb,
                                       mcgraph_->Int32Constant(shift));
      result = graph()->NewNode(machine()->Word32Or(), shifted, result);
    } else if (i > msb_index) {
      int shift = i - msb_index;
      Node* shifted = graph()->NewNode(machine()->Word32Shl(), msb,
                                       mcgraph_->Int32Constant(shift));
      result = graph()->NewNode(machine()->Word32Or(), shifted, result);
    } else {
      result = graph()->NewNode(machine()->Word32Or(), msb, result);
    }
  }

  rep_node[0] = result;
  ReplaceNode(node, rep_node, 1);
}

void SimdScalarLowering::LowerAllTrueOp(Node* node, SimdType rep_type) {
  // AllTrue ops require the input to be of a particular SimdType, but the op
  // itself is always replaced by a Int32x4 with 1 node.
  int num_lanes = NumLanes(rep_type);
  DCHECK_EQ(1, node->InputCount());
  Node** rep = GetReplacementsWithType(node->InputAt(0), rep_type);

  Node** rep_node = zone()->NewArray<Node*>(num_lanes);
  Node* zero = mcgraph_->Int32Constant(0);
  Node* tmp_result = mcgraph_->Int32Constant(1);
  for (int i = 0; i < num_lanes; ++i) {
    Diamond d(graph(), common(),
              graph()->NewNode(machine()->Word32Equal(), rep[i], zero));
    tmp_result = d.Phi(MachineRepresentation::kWord32, zero, tmp_result);
  }
  rep_node[0] = tmp_result;
  ReplaceNode(node, rep_node, 1);
}

void SimdScalarLowering::LowerFloatPseudoMinMax(Node* node, const Operator* op,
                                                bool is_max, SimdType type) {
  DCHECK_EQ(2, node->InputCount());
  Node** rep_left = GetReplacementsWithType(node->InputAt(0), type);
  Node** rep_right = GetReplacementsWithType(node->InputAt(1), type);
  int num_lanes = NumLanes(type);
  Node** rep_node = zone()->NewArray<Node*>(num_lanes);
  MachineRepresentation rep = MachineTypeFrom(type).representation();
  for (int i = 0; i < num_lanes; ++i) {
    Node* cmp = is_max ? graph()->NewNode(op, rep_left[i], rep_right[i])
                       : graph()->NewNode(op, rep_right[i], rep_left[i]);
    Diamond d(graph(), common(), cmp);
    rep_node[i] = d.Phi(rep, rep_right[i], rep_left[i]);
  }
  ReplaceNode(node, rep_node, num_lanes);
}

void SimdScalarLowering::LowerNode(Node* node) {
  SimdType rep_type = ReplacementType(node);
  int num_lanes = NumLanes(rep_type);
  switch (node->opcode()) {
    case IrOpcode::kS128Const: {
      // We could use GetReplacementsWithType for all this, but it adds a lot of
      // nodes, so sign extend the immediates ourselves here.
      DCHECK_EQ(0, node->InputCount());
      Node** rep_node = zone()->NewArray<Node*>(num_lanes);
      S128ImmediateParameter params = S128ImmediateParameterOf(node->op());

      // For all the small ints below, we have a choice of static_cast or bit
      // twiddling, clang seems to be able to optimize either
      // (https://godbolt.org/z/9c65o8) so use static_cast for clarity.
      switch (rep_type) {
        case SimdType::kInt8x16: {
          for (int i = 0; i < num_lanes; ++i) {
            Address data_address = reinterpret_cast<Address>(params.data() + i);
            rep_node[i] = mcgraph_->Int32Constant(static_cast<int32_t>(
                base::ReadLittleEndianValue<int8_t>(data_address)));
          }
          break;
        }
        case SimdType::kInt16x8: {
          int16_t val[kNumLanes16];
          base::Memcpy(val, params.data(), kSimd128Size);
          for (int i = 0; i < num_lanes; ++i) {
            rep_node[i] = mcgraph_->Int32Constant(static_cast<int32_t>(
                base::ReadLittleEndianValue<int16_t>(&val[i])));
          }
          break;
        }
        case SimdType::kInt32x4: {
          uint32_t val[kNumLanes32];
          base::Memcpy(val, params.data(), kSimd128Size);
          for (int i = 0; i < num_lanes; ++i) {
            rep_node[i] = mcgraph_->Int32Constant(
                base::ReadLittleEndianValue<uint32_t>(&val[i]));
          }
          break;
        }
        case SimdType::kInt64x2: {
          uint64_t val[kNumLanes64];
          base::Memcpy(val, params.data(), kSimd128Size);
          for (int i = 0; i < num_lanes; ++i) {
            rep_node[i] = mcgraph_->Int64Constant(
                base::ReadLittleEndianValue<uint64_t>(&val[i]));
          }
          break;
        }
        case SimdType::kFloat32x4: {
          float val[kNumLanes32];
          base::Memcpy(val, params.data(), kSimd128Size);
          for (int i = 0; i < num_lanes; ++i) {
            rep_node[i] = mcgraph_->Float32Constant(
                base::ReadLittleEndianValue<float>(&val[i]));
          }
          break;
        }
        case SimdType::kFloat64x2: {
          double val[kNumLanes64];
          base::Memcpy(val, params.data(), kSimd128Size);
          for (int i = 0; i < num_lanes; ++i) {
            rep_node[i] = mcgraph_->Float64Constant(
                base::ReadLittleEndianValue<double>(&val[i]));
          }
          break;
        }
      }
      ReplaceNode(node, rep_node, num_lanes);
      break;
    }
    case IrOpcode::kStart: {
      int parameter_count = GetParameterCountAfterLowering();
      // Only exchange the node if the parameter count actually changed.
      if (parameter_count != static_cast<int>(signature()->parameter_count())) {
        int delta =
            parameter_count - static_cast<int>(signature()->parameter_count());
        int new_output_count = node->op()->ValueOutputCount() + delta;
        NodeProperties::ChangeOp(node, common()->Start(new_output_count));
      }
      break;
    }
    case IrOpcode::kParameter: {
      DCHECK_EQ(1, node->InputCount());
      int param_count = static_cast<int>(signature()->parameter_count());
      // Only exchange the node if the parameter count actually changed. We do
      // not even have to do the default lowering because the start node,
      // the only input of a parameter node, only changes if the parameter count
      // changes.
      if (GetParameterCountAfterLowering() != param_count) {
        int old_index = ParameterIndexOf(node->op());
        // Parameter index 0 is the instance parameter, we will use old_index to
        // index into the function signature, so we need to decrease it by 1.
        --old_index;
        int new_index =
            GetParameterIndexAfterLoweringSimd128(signature(), old_index);
        // Similarly, the index into function signature needs to account for the
        // instance parameter, so increase it by 1.
        ++new_index;
        NodeProperties::ChangeOp(node, common()->Parameter(new_index));

        if (old_index < 0) {
          break;
        }

        DCHECK(old_index < param_count);

        if (signature()->GetParam(old_index) ==
            MachineRepresentation::kSimd128) {
          Node* new_node[kNumLanes32];
          new_node[0] = node;
          for (int i = 1; i < kNumLanes32; ++i) {
            new_node[i] = graph()->NewNode(common()->Parameter(new_index + i),
                                           graph()->start());
          }
          ReplaceNode(node, new_node, kNumLanes32);
        }
      }
      break;
    }
    case IrOpcode::kSimd128ReverseBytes: {
      DCHECK_EQ(1, node->InputCount());
      SimdType input_type = ReplacementType(node->InputAt(0));
      bool is_float = input_type == SimdType::kFloat32x4 ||
                      input_type == SimdType::kFloat64x2;
      replacements_[node->id()].type =
          is_float ? SimdType::kFloat32x4 : SimdType::kInt32x4;
      Node** rep = GetReplacementsWithType(
          node->InputAt(0),
          is_float ? SimdType::kFloat32x4 : SimdType::kInt32x4);
      Node* rep_node[kNumLanes32];
      for (int i = 0; i < kNumLanes32; ++i) {
        Node* temp = is_float ? graph()->NewNode(
                                    machine()->BitcastFloat32ToInt32(), rep[i])
                              : rep[i];
        temp = graph()->NewNode(machine()->Word32ReverseBytes(), temp);
        rep_node[kNumLanes32 - 1 - i] =
            is_float
                ? graph()->NewNode(machine()->BitcastInt32ToFloat32(), temp)
                : temp;
      }
      ReplaceNode(node, rep_node, kNumLanes32);
      break;
    }
    case IrOpcode::kLoad:
    case IrOpcode::kUnalignedLoad:
    case IrOpcode::kProtectedLoad: {
      LowerLoadOp(node, rep_type);
      break;
    }
    case IrOpcode::kLoadTransform: {
      LowerLoadTransformOp(node, rep_type);
      break;
    }
    case IrOpcode::kStore:
    case IrOpcode::kUnalignedStore:
    case IrOpcode::kProtectedStore: {
      LowerStoreOp(node);
      break;
    }
    case IrOpcode::kReturn: {
      int old_input_count = node->InputCount();
      int return_arity = static_cast<int>(signature()->return_count());
      for (int i = 0; i < return_arity; i++) {
        if (signature()->GetReturn(i) != MachineRepresentation::kSimd128) {
          continue;
        }

        // Return nodes have a hidden input at value 0.
        Node* input = node->InputAt(i + 1);
        if (!HasReplacement(0, input)) {
          continue;
        }

        // V128 return types are lowered to i32x4.
        Node** reps = GetReplacementsWithType(input, rep_type);
        ReplaceNode(input, reps, NumLanes(rep_type));
      }

      DefaultLowering(node);
      // Nothing needs to be done here since inputs did not change.
      if (old_input_count == node->InputCount()) {
        break;
      }

      int new_return_count = GetReturnCountAfterLoweringSimd128(signature());
      if (static_cast<int>(signature()->return_count()) != new_return_count) {
        NodeProperties::ChangeOp(node, common()->Return(new_return_count));
      }
      break;
    }
    case IrOpcode::kCall: {
      // TODO(turbofan): Make wasm code const-correct wrt. CallDescriptor.
      auto call_descriptor =
          const_cast<CallDescriptor*>(CallDescriptorOf(node->op()));
      bool returns_require_lowering =
          GetReturnCountAfterLoweringSimd128(call_descriptor) !=
          static_cast<int>(call_descriptor->ReturnCount());

      // All call arguments are lowered to i32x4 in the call descriptor, so the
      // arguments need to be converted to i32x4 as well.
      for (int i = NodeProperties::PastValueIndex(node) - 1; i >= 0; i--) {
        Node* input = node->InputAt(i);
        if (ReplacementCount(input) == 1) {
          // Special case for extract lanes
          Node** reps = GetReplacements(input);
          ReplaceNode(input, reps, 1);
        } else if (HasReplacement(0, input)) {
          Node** reps = GetReplacementsWithType(input, SimdType::kInt32x4);
          ReplaceNode(input, reps, NumLanes(SimdType::kInt32x4));
        }
      }

      if (DefaultLowering(node) || returns_require_lowering) {
        // We have to adjust the call descriptor.
        const Operator* op = common()->Call(
            GetI32WasmCallDescriptorForSimd(zone(), call_descriptor));
        NodeProperties::ChangeOp(node, op);
      }

      if (!returns_require_lowering) {
        break;
      }

      size_t return_arity = call_descriptor->ReturnCount();

      if (return_arity == 1) {
        // We access the additional return values through projections.
        // Special case for return_arity 1, with multi-returns, we would have
        // already built projections for each return value, and will be handled
        // by the following code.
        Node* rep_node[kNumLanes32];
        for (int i = 0; i < kNumLanes32; ++i) {
          rep_node[i] =
              graph()->NewNode(common()->Projection(i), node, graph()->start());
        }
        ReplaceNode(node, rep_node, kNumLanes32);
        break;
      }

      ZoneVector<Node*> projections(return_arity, zone());
      NodeProperties::CollectValueProjections(node, projections.data(),
                                              return_arity);

      for (size_t old_index = 0, new_index = 0; old_index < return_arity;
           ++old_index, ++new_index) {
        Node* use_node = projections[old_index];
        DCHECK_EQ(ProjectionIndexOf(use_node->op()), old_index);
        DCHECK_EQ(GetReturnIndexAfterLowering(call_descriptor,
                                              static_cast<int>(old_index)),
                  static_cast<int>(new_index));
        if (new_index != old_index) {
          NodeProperties::ChangeOp(use_node, common()->Projection(new_index));
        }
        if (call_descriptor->GetReturnType(old_index).representation() ==
            MachineRepresentation::kSimd128) {
          Node* rep_node[kNumLanes32];
          for (int i = 0; i < kNumLanes32; ++i) {
            rep_node[i] = graph()->NewNode(common()->Projection(new_index + i),
                                           node, graph()->start());
          }
          ReplaceNode(use_node, rep_node, kNumLanes32);
          new_index += kNumLanes32 - 1;
        }
      }
      break;
    }
    case IrOpcode::kPhi: {
      MachineRepresentation rep = PhiRepresentationOf(node->op());
      if (rep == MachineRepresentation::kSimd128) {
        // The replacement nodes have already been created, we only have to
        // replace placeholder nodes.
        Node** rep_node = GetReplacements(node);
        for (int i = 0; i < node->op()->ValueInputCount(); ++i) {
          Node** rep_input =
              GetReplacementsWithType(node->InputAt(i), rep_type);
          for (int j = 0; j < num_lanes; j++) {
            rep_node[j]->ReplaceInput(i, rep_input[j]);
          }
        }
      } else {
        DefaultLowering(node);
      }
      break;
    }
    case IrOpcode::kI64x2Add: {
      LowerBinaryOp(node, rep_type, machine()->Int64Add());
      break;
    }
    case IrOpcode::kI64x2Sub: {
      LowerBinaryOp(node, rep_type, machine()->Int64Sub());
      break;
    }
    case IrOpcode::kI64x2Mul: {
      LowerBinaryOp(node, rep_type, machine()->Int64Mul());
      break;
    }
#define I32X4_BINOP_CASE(opcode, instruction)                \
  case IrOpcode::opcode: {                                   \
    LowerBinaryOp(node, rep_type, machine()->instruction()); \
    break;                                                   \
  }
      I32X4_BINOP_CASE(kI32x4Add, Int32Add)
      I32X4_BINOP_CASE(kI32x4Sub, Int32Sub)
      I32X4_BINOP_CASE(kI32x4Mul, Int32Mul)
      I32X4_BINOP_CASE(kS128And, Word32And)
      I32X4_BINOP_CASE(kS128Or, Word32Or)
      I32X4_BINOP_CASE(kS128Xor, Word32Xor)
#undef I32X4_BINOP_CASE
    case IrOpcode::kI32x4AddHoriz: {
      LowerBinaryOp(node, rep_type, machine()->Int32Add(), false);
      break;
    }
    case IrOpcode::kI16x8AddHoriz: {
      LowerBinaryOpForSmallInt(node, rep_type, machine()->Int32Add(), false);
      break;
    }
    case IrOpcode::kI16x8Add:
    case IrOpcode::kI8x16Add: {
      LowerBinaryOpForSmallInt(node, rep_type, machine()->Int32Add());
      break;
    }
    case IrOpcode::kI16x8Sub:
    case IrOpcode::kI8x16Sub: {
      LowerBinaryOpForSmallInt(node, rep_type, machine()->Int32Sub());
      break;
    }
    case IrOpcode::kI16x8Mul:
    case IrOpcode::kI8x16Mul: {
      LowerBinaryOpForSmallInt(node, rep_type, machine()->Int32Mul());
      break;
    }
    case IrOpcode::kI16x8AddSatS:
    case IrOpcode::kI8x16AddSatS: {
      LowerSaturateBinaryOp(node, rep_type, machine()->Int32Add(), true);
      break;
    }
    case IrOpcode::kI16x8SubSatS:
    case IrOpcode::kI8x16SubSatS: {
      LowerSaturateBinaryOp(node, rep_type, machine()->Int32Sub(), true);
      break;
    }
    case IrOpcode::kI16x8AddSatU:
    case IrOpcode::kI8x16AddSatU: {
      LowerSaturateBinaryOp(node, rep_type, machine()->Int32Add(), false);
      break;
    }
    case IrOpcode::kI16x8SubSatU:
    case IrOpcode::kI8x16SubSatU: {
      LowerSaturateBinaryOp(node, rep_type, machine()->Int32Sub(), false);
      break;
    }
    case IrOpcode::kI32x4MaxS:
    case IrOpcode::kI16x8MaxS:
    case IrOpcode::kI8x16MaxS: {
      LowerIntMinMax(node, machine()->Int32LessThan(), true, rep_type);
      break;
    }
    case IrOpcode::kI32x4MinS:
    case IrOpcode::kI16x8MinS:
    case IrOpcode::kI8x16MinS: {
      LowerIntMinMax(node, machine()->Int32LessThan(), false, rep_type);
      break;
    }
    case IrOpcode::kI32x4MaxU:
    case IrOpcode::kI16x8MaxU:
    case IrOpcode::kI8x16MaxU: {
      LowerIntMinMax(node, machine()->Uint32LessThan(), true, rep_type);
      break;
    }
    case IrOpcode::kI32x4MinU:
    case IrOpcode::kI16x8MinU:
    case IrOpcode::kI8x16MinU: {
      LowerIntMinMax(node, machine()->Uint32LessThan(), false, rep_type);
      break;
    }
    case IrOpcode::kI32x4DotI16x8S: {
      // i32x4.dot_i16x8_s wants the inputs to be i16x8, but outputs to i32x4.
      DCHECK_EQ(2, node->InputCount());
      Node** rep_left =
          GetReplacementsWithType(node->InputAt(0), SimdType::kInt16x8);
      Node** rep_right =
          GetReplacementsWithType(node->InputAt(1), SimdType::kInt16x8);
      int num_lanes = NumLanes(rep_type);
      Node** rep_node = zone()->NewArray<Node*>(num_lanes);
      for (int i = 0; i < num_lanes; ++i) {
        Node* lo = graph()->NewNode(machine()->Int32Mul(), rep_left[i * 2],
                                    rep_right[i * 2]);
        Node* hi = graph()->NewNode(machine()->Int32Mul(), rep_left[i * 2 + 1],
                                    rep_right[i * 2 + 1]);
        rep_node[i] = graph()->NewNode(machine()->Int32Add(), lo, hi);
      }
      ReplaceNode(node, rep_node, num_lanes);
      break;
    }
    case IrOpcode::kI64x2Neg: {
      DCHECK_EQ(1, node->InputCount());
      Node** rep = GetReplacementsWithType(node->InputAt(0), rep_type);
      int num_lanes = NumLanes(rep_type);
      Node** rep_node = zone()->NewArray<Node*>(num_lanes);
      Node* zero = graph()->NewNode(common()->Int64Constant(0));
      for (int i = 0; i < num_lanes; ++i) {
        rep_node[i] = graph()->NewNode(machine()->Int64Sub(), zero, rep[i]);
      }
      ReplaceNode(node, rep_node, num_lanes);
      break;
    }
    case IrOpcode::kI32x4Neg:
    case IrOpcode::kI16x8Neg:
    case IrOpcode::kI8x16Neg: {
      DCHECK_EQ(1, node->InputCount());
      Node** rep = GetReplacementsWithType(node->InputAt(0), rep_type);
      int num_lanes = NumLanes(rep_type);
      Node** rep_node = zone()->NewArray<Node*>(num_lanes);
      Node* zero = graph()->NewNode(common()->Int32Constant(0));
      for (int i = 0; i < num_lanes; ++i) {
        rep_node[i] = graph()->NewNode(machine()->Int32Sub(), zero, rep[i]);
        if (node->opcode() == IrOpcode::kI16x8Neg) {
          rep_node[i] = FixUpperBits(rep_node[i], kShift16);
        } else if (node->opcode() == IrOpcode::kI8x16Neg) {
          rep_node[i] = FixUpperBits(rep_node[i], kShift8);
        }
      }
      ReplaceNode(node, rep_node, num_lanes);
      break;
    }
    case IrOpcode::kI32x4Abs:
    case IrOpcode::kI16x8Abs:
    case IrOpcode::kI8x16Abs: {
      // From https://stackoverflow.com/a/14194764
      // abs(x) = (x XOR y) - y
      Node** rep = GetReplacementsWithType(node->InputAt(0), rep_type);
      Node** rep_node = zone()->NewArray<Node*>(num_lanes);
      for (int i = 0; i < num_lanes; ++i) {
        // It's fine to shift by 31 even for i8x16 since each node is
        // effectively expanded to 32 bits.
        Node* y = graph()->NewNode(machine()->Word32Sar(), rep[i],
                                   mcgraph_->Int32Constant(31));
        rep_node[i] = graph()->NewNode(
            machine()->Int32Sub(),
            graph()->NewNode(machine()->Word32Xor(), rep[i], y), y);
        if (node->opcode() == IrOpcode::kI16x8Neg) {
          rep_node[i] = FixUpperBits(rep_node[i], kShift16);
        } else if (node->opcode() == IrOpcode::kI8x16Neg) {
          rep_node[i] = FixUpperBits(rep_node[i], kShift8);
        }
      }
      ReplaceNode(node, rep_node, num_lanes);
      break;
    }
    case IrOpcode::kS128Zero: {
      DCHECK_EQ(0, node->InputCount());
      Node* rep_node[kNumLanes32];
      for (int i = 0; i < kNumLanes32; ++i) {
        rep_node[i] = mcgraph_->Int32Constant(0);
      }
      ReplaceNode(node, rep_node, kNumLanes32);
      break;
    }
    case IrOpcode::kS128Not: {
      DCHECK_EQ(1, node->InputCount());
      Node** rep = GetReplacementsWithType(node->InputAt(0), rep_type);
      Node* rep_node[kNumLanes32];
      Node* mask = graph()->NewNode(common()->Int32Constant(0xFFFFFFFF));
      for (int i = 0; i < kNumLanes32; ++i) {
        rep_node[i] = graph()->NewNode(machine()->Word32Xor(), rep[i], mask);
      }
      ReplaceNode(node, rep_node, kNumLanes32);
      break;
    }
    case IrOpcode::kS128AndNot: {
      DCHECK_EQ(2, node->InputCount());
      Node** rep_left = GetReplacementsWithType(node->InputAt(0), rep_type);
      Node** rep_right = GetReplacementsWithType(node->InputAt(1), rep_type);
      int num_lanes = NumLanes(rep_type);
      Node** rep_node = zone()->NewArray<Node*>(num_lanes);
      Node* mask = graph()->NewNode(common()->Int32Constant(0xFFFFFFFF));
      for (int i = 0; i < num_lanes; ++i) {
        Node* not_rep_right =
            graph()->NewNode(machine()->Word32Xor(), rep_right[i], mask);
        rep_node[i] = graph()->NewNode(machine()->Word32And(), rep_left[i],
                                       not_rep_right);
      }
      ReplaceNode(node, rep_node, num_lanes);
      break;
    }
    case IrOpcode::kI32x4SConvertF32x4: {
      LowerConvertFromFloat(node, true);
      break;
    }
    case IrOpcode::kI32x4UConvertF32x4: {
      LowerConvertFromFloat(node, false);
      break;
    }
    case IrOpcode::kI32x4SConvertI16x8Low: {
      LowerConvertFromInt(node, SimdType::kInt16x8, SimdType::kInt32x4, true,
                          0);
      break;
    }
    case IrOpcode::kI32x4SConvertI16x8High: {
      LowerConvertFromInt(node, SimdType::kInt16x8, SimdType::kInt32x4, true,
                          4);
      break;
    }
    case IrOpcode::kI32x4UConvertI16x8Low: {
      LowerConvertFromInt(node, SimdType::kInt16x8, SimdType::kInt32x4, false,
                          0);
      break;
    }
    case IrOpcode::kI32x4UConvertI16x8High: {
      LowerConvertFromInt(node, SimdType::kInt16x8, SimdType::kInt32x4, false,
                          4);
      break;
    }
    case IrOpcode::kI16x8SConvertI8x16Low: {
      LowerConvertFromInt(node, SimdType::kInt8x16, SimdType::kInt16x8, true,
                          0);
      break;
    }
    case IrOpcode::kI16x8SConvertI8x16High: {
      LowerConvertFromInt(node, SimdType::kInt8x16, SimdType::kInt16x8, true,
                          8);
      break;
    }
    case IrOpcode::kI16x8UConvertI8x16Low: {
      LowerConvertFromInt(node, SimdType::kInt8x16, SimdType::kInt16x8, false,
                          0);
      break;
    }
    case IrOpcode::kI16x8UConvertI8x16High: {
      LowerConvertFromInt(node, SimdType::kInt8x16, SimdType::kInt16x8, false,
                          8);
      break;
    }
    case IrOpcode::kI16x8SConvertI32x4: {
      LowerPack(node, SimdType::kInt32x4, SimdType::kInt16x8, true);
      break;
    }
    case IrOpcode::kI16x8UConvertI32x4: {
      LowerPack(node, SimdType::kInt32x4, SimdType::kInt16x8, false);
      break;
    }
    case IrOpcode::kI8x16SConvertI16x8: {
      LowerPack(node, SimdType::kInt16x8, SimdType::kInt8x16, true);
      break;
    }
    case IrOpcode::kI8x16UConvertI16x8: {
      LowerPack(node, SimdType::kInt16x8, SimdType::kInt8x16, false);
      break;
    }
    case IrOpcode::kI64x2Shl:
    case IrOpcode::kI32x4Shl:
    case IrOpcode::kI16x8Shl:
    case IrOpcode::kI8x16Shl:
    case IrOpcode::kI64x2ShrS:
    case IrOpcode::kI32x4ShrS:
    case IrOpcode::kI16x8ShrS:
    case IrOpcode::kI8x16ShrS:
    case IrOpcode::kI64x2ShrU:
    case IrOpcode::kI32x4ShrU:
    case IrOpcode::kI16x8ShrU:
    case IrOpcode::kI8x16ShrU: {
      LowerShiftOp(node, rep_type);
      break;
    }
    case IrOpcode::kF32x4AddHoriz: {
      LowerBinaryOp(node, rep_type, machine()->Float32Add(), false);
      break;
    }
#define F32X4_BINOP_CASE(name)                                 \
  case IrOpcode::kF32x4##name: {                               \
    LowerBinaryOp(node, rep_type, machine()->Float32##name()); \
    break;                                                     \
  }
      F32X4_BINOP_CASE(Add)
      F32X4_BINOP_CASE(Sub)
      F32X4_BINOP_CASE(Mul)
      F32X4_BINOP_CASE(Div)
      F32X4_BINOP_CASE(Min)
      F32X4_BINOP_CASE(Max)
    case IrOpcode::kF32x4Pmin: {
      LowerFloatPseudoMinMax(node, machine()->Float32LessThan(), false,
                             rep_type);
      break;
    }
    case IrOpcode::kF32x4Pmax: {
      LowerFloatPseudoMinMax(node, machine()->Float32LessThan(), true,
                             rep_type);
      break;
    }
#undef F32X4_BINOP_CASE
#define F32X4_UNOP_CASE(name)                                 \
  case IrOpcode::kF32x4##name: {                              \
    LowerUnaryOp(node, rep_type, machine()->Float32##name()); \
    break;                                                    \
  }
      F32X4_UNOP_CASE(Abs)
      F32X4_UNOP_CASE(Neg)
      F32X4_UNOP_CASE(Sqrt)
#undef F32X4_UNOP_CASE
    case IrOpcode::kF32x4Ceil: {
      LowerUnaryOp(node, rep_type, machine()->Float32RoundUp().op());
      break;
    }
    case IrOpcode::kF32x4Floor: {
      LowerUnaryOp(node, rep_type, machine()->Float32RoundDown().op());
      break;
    }
    case IrOpcode::kF32x4Trunc: {
      LowerUnaryOp(node, rep_type, machine()->Float32RoundTruncate().op());
      break;
    }
    case IrOpcode::kF32x4NearestInt: {
      LowerUnaryOp(node, rep_type, machine()->Float32RoundTiesEven().op());
      break;
    }
    case IrOpcode::kF32x4RecipApprox:
    case IrOpcode::kF32x4RecipSqrtApprox: {
      DCHECK_EQ(1, node->InputCount());
      Node** rep = GetReplacementsWithType(node->InputAt(0), rep_type);
      Node** rep_node = zone()->NewArray<Node*>(num_lanes);
      Node* float_one = graph()->NewNode(common()->Float32Constant(1.0));
      for (int i = 0; i < num_lanes; ++i) {
        Node* tmp = rep[i];
        if (node->opcode() == IrOpcode::kF32x4RecipSqrtApprox) {
          tmp = graph()->NewNode(machine()->Float32Sqrt(), rep[i]);
        }
        rep_node[i] = graph()->NewNode(machine()->Float32Div(), float_one, tmp);
      }
      ReplaceNode(node, rep_node, num_lanes);
      break;
    }
    case IrOpcode::kF32x4SConvertI32x4: {
      LowerUnaryOp(node, SimdType::kInt32x4, machine()->RoundInt32ToFloat32());
      break;
    }
    case IrOpcode::kF32x4UConvertI32x4: {
      LowerUnaryOp(node, SimdType::kInt32x4, machine()->RoundUint32ToFloat32());
      break;
    }
    case IrOpcode::kF64x2Abs: {
      LowerUnaryOp(node, rep_type, machine()->Float64Abs());
      break;
    }
    case IrOpcode::kF64x2Neg: {
      LowerUnaryOp(node, rep_type, machine()->Float64Neg());
      break;
    }
    case IrOpcode::kF64x2Sqrt: {
      LowerUnaryOp(node, rep_type, machine()->Float64Sqrt());
      break;
    }
    case IrOpcode::kF64x2Add: {
      LowerBinaryOp(node, rep_type, machine()->Float64Add());
      break;
    }
    case IrOpcode::kF64x2Sub: {
      LowerBinaryOp(node, rep_type, machine()->Float64Sub());
      break;
    }
    case IrOpcode::kF64x2Mul: {
      LowerBinaryOp(node, rep_type, machine()->Float64Mul());
      break;
    }
    case IrOpcode::kF64x2Div: {
      LowerBinaryOp(node, rep_type, machine()->Float64Div());
      break;
    }
    case IrOpcode::kF64x2Min: {
      LowerBinaryOp(node, rep_type, machine()->Float64Min());
      break;
    }
    case IrOpcode::kF64x2Max: {
      LowerBinaryOp(node, rep_type, machine()->Float64Max());
      break;
    }
    case IrOpcode::kF64x2Pmin: {
      LowerFloatPseudoMinMax(node, machine()->Float64LessThan(), false,
                             rep_type);
      break;
    }
    case IrOpcode::kF64x2Pmax: {
      LowerFloatPseudoMinMax(node, machine()->Float64LessThan(), true,
                             rep_type);
      break;
    }
    case IrOpcode::kF64x2Ceil: {
      LowerUnaryOp(node, rep_type, machine()->Float64RoundUp().op());
      break;
    }
    case IrOpcode::kF64x2Floor: {
      LowerUnaryOp(node, rep_type, machine()->Float64RoundDown().op());
      break;
    }
    case IrOpcode::kF64x2Trunc: {
      LowerUnaryOp(node, rep_type, machine()->Float64RoundTruncate().op());
      break;
    }
    case IrOpcode::kF64x2NearestInt: {
      LowerUnaryOp(node, rep_type, machine()->Float64RoundTiesEven().op());
      break;
    }
    case IrOpcode::kF64x2Splat:
    case IrOpcode::kF32x4Splat:
    case IrOpcode::kI64x2Splat:
    case IrOpcode::kI32x4Splat:
    case IrOpcode::kI16x8Splat:
    case IrOpcode::kI8x16Splat: {
      Node** rep_node = zone()->NewArray<Node*>(num_lanes);
      Node* val = (HasReplacement(0, node->InputAt(0)))
                      ? GetReplacements(node->InputAt(0))[0]
                      : node->InputAt(0);

      // I16 and I8 are placed in Word32 nodes, we need to mask them
      // accordingly, to account for overflows, then sign extend them.
      if (node->opcode() == IrOpcode::kI16x8Splat) {
        val = graph()->NewNode(machine()->SignExtendWord16ToInt32(),
                               Mask(val, kMask16));
      } else if (node->opcode() == IrOpcode::kI8x16Splat) {
        val = graph()->NewNode(machine()->SignExtendWord8ToInt32(),
                               Mask(val, kMask8));
      }

      for (int i = 0; i < num_lanes; ++i) {
        rep_node[i] = val;
      }
      ReplaceNode(node, rep_node, num_lanes);
      break;
    }
    case IrOpcode::kF64x2ExtractLane:
    case IrOpcode::kF32x4ExtractLane:
    case IrOpcode::kI64x2ExtractLane:
    case IrOpcode::kI32x4ExtractLane:
    case IrOpcode::kI16x8ExtractLaneU:
    case IrOpcode::kI16x8ExtractLaneS:
    case IrOpcode::kI8x16ExtractLaneU:
    case IrOpcode::kI8x16ExtractLaneS: {
      int32_t lane = OpParameter<int32_t>(node->op());
      Node** rep_node = zone()->NewArray<Node*>(1);
      rep_node[0] = GetReplacementsWithType(node->InputAt(0), rep_type)[lane];

      // If unsigned, mask the top bits.
      if (node->opcode() == IrOpcode::kI16x8ExtractLaneU) {
        rep_node[0] = Mask(rep_node[0], kMask16);
      } else if (node->opcode() == IrOpcode::kI8x16ExtractLaneU) {
        rep_node[0] = Mask(rep_node[0], kMask8);
      }

      ReplaceNode(node, rep_node, 1);
      break;
    }
    case IrOpcode::kF64x2ReplaceLane:
    case IrOpcode::kF32x4ReplaceLane:
    case IrOpcode::kI64x2ReplaceLane:
    case IrOpcode::kI32x4ReplaceLane:
    case IrOpcode::kI16x8ReplaceLane:
    case IrOpcode::kI8x16ReplaceLane: {
      DCHECK_EQ(2, node->InputCount());
      Node* repNode = node->InputAt(1);
      int32_t lane = OpParameter<int32_t>(node->op());
      Node** old_rep_node = GetReplacementsWithType(node->InputAt(0), rep_type);
      Node** rep_node = zone()->NewArray<Node*>(num_lanes);
      for (int i = 0; i < num_lanes; ++i) {
        rep_node[i] = old_rep_node[i];
      }
      if (HasReplacement(0, repNode)) {
        rep_node[lane] = GetReplacements(repNode)[0];
      } else {
        rep_node[lane] = repNode;
      }

      // The replacement nodes for these opcodes are in Word32, and we always
      // store nodes in sign extended form (and mask to account for overflows.)
      if (node->opcode() == IrOpcode::kI16x8ReplaceLane) {
        rep_node[lane] = graph()->NewNode(machine()->SignExtendWord16ToInt32(),
                                          Mask(rep_node[lane], kMask16));
      } else if (node->opcode() == IrOpcode::kI8x16ReplaceLane) {
        rep_node[lane] = graph()->NewNode(machine()->SignExtendWord8ToInt32(),
                                          Mask(rep_node[lane], kMask8));
      }

      ReplaceNode(node, rep_node, num_lanes);
      break;
    }
#define COMPARISON_CASE(type, simd_op, lowering_op, invert)                    \
  case IrOpcode::simd_op: {                                                    \
    LowerCompareOp(node, SimdType::k##type, machine()->lowering_op(), invert); \
    break;                                                                     \
  }
      COMPARISON_CASE(Float64x2, kF64x2Eq, Float64Equal, false)
      COMPARISON_CASE(Float64x2, kF64x2Lt, Float64LessThan, false)
      COMPARISON_CASE(Float64x2, kF64x2Le, Float64LessThanOrEqual, false)
      COMPARISON_CASE(Float32x4, kF32x4Eq, Float32Equal, false)
      COMPARISON_CASE(Float32x4, kF32x4Lt, Float32LessThan, false)
      COMPARISON_CASE(Float32x4, kF32x4Le, Float32LessThanOrEqual, false)
      COMPARISON_CASE(Float32x4, kF32x4Gt, Float32LessThan, true)
      COMPARISON_CASE(Float32x4, kF32x4Ge, Float32LessThanOrEqual, true)
      COMPARISON_CASE(Int32x4, kI32x4Eq, Word32Equal, false)
      COMPARISON_CASE(Int32x4, kI32x4LtS, Int32LessThan, false)
      COMPARISON_CASE(Int32x4, kI32x4LeS, Int32LessThanOrEqual, false)
      COMPARISON_CASE(Int32x4, kI32x4GtS, Int32LessThan, true)
      COMPARISON_CASE(Int32x4, kI32x4GeS, Int32LessThanOrEqual, true)
      COMPARISON_CASE(Int32x4, kI32x4LtU, Uint32LessThan, false)
      COMPARISON_CASE(Int32x4, kI32x4LeU, Uint32LessThanOrEqual, false)
      COMPARISON_CASE(Int32x4, kI32x4GtU, Uint32LessThan, true)
      COMPARISON_CASE(Int32x4, kI32x4GeU, Uint32LessThanOrEqual, true)
      COMPARISON_CASE(Int16x8, kI16x8Eq, Word32Equal, false)
      COMPARISON_CASE(Int16x8, kI16x8LtS, Int32LessThan, false)
      COMPARISON_CASE(Int16x8, kI16x8LeS, Int32LessThanOrEqual, false)
      COMPARISON_CASE(Int16x8, kI16x8GtS, Int32LessThan, true)
      COMPARISON_CASE(Int16x8, kI16x8GeS, Int32LessThanOrEqual, true)
      COMPARISON_CASE(Int16x8, kI16x8LtU, Uint32LessThan, false)
      COMPARISON_CASE(Int16x8, kI16x8LeU, Uint32LessThanOrEqual, false)
      COMPARISON_CASE(Int16x8, kI16x8GtU, Uint32LessThan, true)
      COMPARISON_CASE(Int16x8, kI16x8GeU, Uint32LessThanOrEqual, true)
      COMPARISON_CASE(Int8x16, kI8x16Eq, Word32Equal, false)
      COMPARISON_CASE(Int8x16, kI8x16LtS, Int32LessThan, false)
      COMPARISON_CASE(Int8x16, kI8x16LeS, Int32LessThanOrEqual, false)
      COMPARISON_CASE(Int8x16, kI8x16GtS, Int32LessThan, true)
      COMPARISON_CASE(Int8x16, kI8x16GeS, Int32LessThanOrEqual, true)
      COMPARISON_CASE(Int8x16, kI8x16LtU, Uint32LessThan, false)
      COMPARISON_CASE(Int8x16, kI8x16LeU, Uint32LessThanOrEqual, false)
      COMPARISON_CASE(Int8x16, kI8x16GtU, Uint32LessThan, true)
      COMPARISON_CASE(Int8x16, kI8x16GeU, Uint32LessThanOrEqual, true)
#undef COMPARISON_CASE
    case IrOpcode::kF64x2Ne: {
      LowerNotEqual(node, SimdType::kFloat64x2, machine()->Float64Equal());
      break;
    }
    case IrOpcode::kF32x4Ne: {
      LowerNotEqual(node, SimdType::kFloat32x4, machine()->Float32Equal());
      break;
    }
    case IrOpcode::kI32x4Ne: {
      LowerNotEqual(node, SimdType::kInt32x4, machine()->Word32Equal());
      break;
    }
    case IrOpcode::kI16x8Ne: {
      LowerNotEqual(node, SimdType::kInt16x8, machine()->Word32Equal());
      break;
    }
    case IrOpcode::kI8x16Ne: {
      LowerNotEqual(node, SimdType::kInt8x16, machine()->Word32Equal());
      break;
    }
    case IrOpcode::kS128Select: {
      DCHECK_EQ(3, node->InputCount());
      DCHECK(ReplacementType(node->InputAt(0)) == SimdType::kInt32x4 ||
             ReplacementType(node->InputAt(0)) == SimdType::kInt16x8 ||
             ReplacementType(node->InputAt(0)) == SimdType::kInt8x16);
      Node** boolean_input =
          GetReplacementsWithType(node->InputAt(0), rep_type);
      Node** rep_left = GetReplacementsWithType(node->InputAt(1), rep_type);
      Node** rep_right = GetReplacementsWithType(node->InputAt(2), rep_type);
      Node** rep_node = zone()->NewArray<Node*>(num_lanes);
      for (int i = 0; i < num_lanes; ++i) {
        Node* tmp1 =
            graph()->NewNode(machine()->Word32Xor(), rep_left[i], rep_right[i]);
        Node* tmp2 =
            graph()->NewNode(machine()->Word32And(), boolean_input[i], tmp1);
        rep_node[i] =
            graph()->NewNode(machine()->Word32Xor(), rep_right[i], tmp2);
      }
      ReplaceNode(node, rep_node, num_lanes);
      break;
    }
    case IrOpcode::kI8x16Swizzle: {
      DCHECK_EQ(2, node->InputCount());
      Node** rep_left = GetReplacementsWithType(node->InputAt(0), rep_type);
      Node** indices = GetReplacementsWithType(node->InputAt(1), rep_type);
      Node** rep_nodes = zone()->NewArray<Node*>(num_lanes);
      Node* stack_slot = graph()->NewNode(
          machine()->StackSlot(MachineRepresentation::kSimd128));

      // Push all num_lanes values into stack slot.
      const Operator* store_op = machine()->Store(
          StoreRepresentation(MachineRepresentation::kWord8, kNoWriteBarrier));
      Node* effect_input = graph()->start();
      for (int i = num_lanes - 1; i >= 0; i--) {
        // We want all the stores to happen first before any of the loads
        // below, so connect them via effect edge from i-1 to i.
        Node* store =
            graph()->NewNode(store_op, stack_slot, mcgraph_->Int32Constant(i),
                             rep_left[i], effect_input, graph()->start());
        effect_input = store;
      }

      for (int i = num_lanes - 1; i >= 0; i--) {
        // Only select lane when index is < num_lanes, otherwise write 0 to
        // lane. Use Uint32 to take care of negative indices.
        Diamond d(graph(), common(),
                  graph()->NewNode(machine()->Uint32LessThan(), indices[i],
                                   mcgraph_->Int32Constant(num_lanes)));

        Node* load =
            graph()->NewNode(machine()->Load(LoadRepresentation::Uint8()),
                             stack_slot, indices[i], effect_input, d.if_true);

        rep_nodes[i] = d.Phi(MachineRepresentation::kWord8, load,
                             mcgraph_->Int32Constant(0));
      }

      ReplaceNode(node, rep_nodes, num_lanes);
      break;
    }
    case IrOpcode::kI8x16Shuffle: {
      DCHECK_EQ(2, node->InputCount());
      S128ImmediateParameter shuffle = S128ImmediateParameterOf(node->op());
      Node** rep_left = GetReplacementsWithType(node->InputAt(0), rep_type);
      Node** rep_right = GetReplacementsWithType(node->InputAt(1), rep_type);
      Node** rep_node = zone()->NewArray<Node*>(16);
      for (int i = 0; i < 16; i++) {
        int lane = shuffle[i];
        rep_node[i] = lane < 16 ? rep_left[lane] : rep_right[lane - 16];
      }
      ReplaceNode(node, rep_node, 16);
      break;
    }
    case IrOpcode::kV32x4AnyTrue:
    case IrOpcode::kV16x8AnyTrue:
    case IrOpcode::kV8x16AnyTrue: {
      DCHECK_EQ(1, node->InputCount());
      // AnyTrue always returns a I32x4, and can work with inputs of any shape,
      // but we still need GetReplacementsWithType if input is float.
      DCHECK_EQ(ReplacementType(node), SimdType::kInt32x4);
      Node** reps = GetReplacementsWithType(node->InputAt(0), rep_type);
      Node** rep_node = zone()->NewArray<Node*>(1);
      Node* true_node = mcgraph_->Int32Constant(1);
      Node* zero = mcgraph_->Int32Constant(0);
      Node* tmp_result = zero;
      for (int i = 0; i < num_lanes; ++i) {
        Diamond d(graph(), common(),
                  graph()->NewNode(machine()->Word32Equal(), reps[i], zero));
        tmp_result =
            d.Phi(MachineRepresentation::kWord32, tmp_result, true_node);
      }
      rep_node[0] = tmp_result;
      ReplaceNode(node, rep_node, 1);
      break;
    }
    case IrOpcode::kV32x4AllTrue: {
      LowerAllTrueOp(node, SimdType::kInt32x4);
      break;
    }
    case IrOpcode::kV16x8AllTrue: {
      LowerAllTrueOp(node, SimdType::kInt16x8);
      break;
    }
    case IrOpcode::kV8x16AllTrue: {
      LowerAllTrueOp(node, SimdType::kInt8x16);
      break;
    }
    case IrOpcode::kI8x16BitMask: {
      LowerBitMaskOp(node, rep_type, 7);
      break;
    }
    case IrOpcode::kI16x8BitMask: {
      LowerBitMaskOp(node, rep_type, 15);
      break;
    }
    case IrOpcode::kI32x4BitMask: {
      LowerBitMaskOp(node, rep_type, 31);
      break;
    }
    case IrOpcode::kI8x16RoundingAverageU:
    case IrOpcode::kI16x8RoundingAverageU: {
      DCHECK_EQ(2, node->InputCount());
      Node** rep_left = GetReplacementsWithType(node->InputAt(0), rep_type);
      Node** rep_right = GetReplacementsWithType(node->InputAt(1), rep_type);
      int num_lanes = NumLanes(rep_type);
      Node** rep_node = zone()->NewArray<Node*>(num_lanes);
      // Nodes are stored signed, so mask away the top bits.
      // rounding_average(left, right) = (left + right + 1) >> 1
      const int bit_mask = num_lanes == 16 ? kMask8 : kMask16;
      for (int i = 0; i < num_lanes; ++i) {
        Node* mask_left = graph()->NewNode(machine()->Word32And(), rep_left[i],
                                           mcgraph_->Int32Constant(bit_mask));
        Node* mask_right =
            graph()->NewNode(machine()->Word32And(), rep_right[i],
                             mcgraph_->Int32Constant(bit_mask));
        Node* left_plus_right_plus_one = graph()->NewNode(
            machine()->Int32Add(),
            graph()->NewNode(machine()->Int32Add(), mask_left, mask_right),
            mcgraph_->Int32Constant(1));
        rep_node[i] =
            graph()->NewNode(machine()->Word32Shr(), left_plus_right_plus_one,
                             mcgraph_->Int32Constant(1));
      }
      ReplaceNode(node, rep_node, num_lanes);
      break;
    }
    default: {
      DefaultLowering(node);
    }
  }
}

bool SimdScalarLowering::DefaultLowering(Node* node) {
  bool something_changed = false;
  for (int i = NodeProperties::PastValueIndex(node) - 1; i >= 0; i--) {
    Node* input = node->InputAt(i);
    if (HasReplacement(0, input)) {
      something_changed = true;
      node->ReplaceInput(i, GetReplacements(input)[0]);
    }
    if (ReplacementCount(input) > 1 && HasReplacement(1, input)) {
      something_changed = true;
      for (int j = 1; j < ReplacementCount(input); ++j) {
        node->InsertInput(zone(), i + j, GetReplacements(input)[j]);
      }
    }
  }
  return something_changed;
}

void SimdScalarLowering::ReplaceNode(Node* old, Node** new_nodes, int count) {
  replacements_[old->id()].node = zone()->NewArray<Node*>(count);
  for (int i = 0; i < count; ++i) {
    replacements_[old->id()].node[i] = new_nodes[i];
  }
  replacements_[old->id()].num_replacements = count;
}

bool SimdScalarLowering::HasReplacement(size_t index, Node* node) {
  return replacements_[node->id()].node != nullptr &&
         replacements_[node->id()].node[index] != nullptr;
}

SimdScalarLowering::SimdType SimdScalarLowering::ReplacementType(Node* node) {
  return replacements_[node->id()].type;
}

Node** SimdScalarLowering::GetReplacements(Node* node) {
  Node** result = replacements_[node->id()].node;
  DCHECK(result);
  return result;
}

int SimdScalarLowering::ReplacementCount(Node* node) {
  return replacements_[node->id()].num_replacements;
}

void SimdScalarLowering::Int32ToFloat32(Node** replacements, Node** result) {
  for (int i = 0; i < kNumLanes32; ++i) {
    if (replacements[i] != nullptr) {
      result[i] =
          graph()->NewNode(machine()->BitcastInt32ToFloat32(), replacements[i]);
    } else {
      result[i] = nullptr;
    }
  }
}

void SimdScalarLowering::Int64ToFloat64(Node** replacements, Node** result) {
  for (int i = 0; i < kNumLanes64; ++i) {
    if (replacements[i] != nullptr) {
      result[i] =
          graph()->NewNode(machine()->BitcastInt64ToFloat64(), replacements[i]);
    } else {
      result[i] = nullptr;
    }
  }
}

void SimdScalarLowering::Float64ToInt64(Node** replacements, Node** result) {
  for (int i = 0; i < kNumLanes64; ++i) {
    if (replacements[i] != nullptr) {
      result[i] =
          graph()->NewNode(machine()->BitcastFloat64ToInt64(), replacements[i]);
    } else {
      result[i] = nullptr;
    }
  }
}

void SimdScalarLowering::Float32ToInt32(Node** replacements, Node** result) {
  for (int i = 0; i < kNumLanes32; ++i) {
    if (replacements[i] != nullptr) {
      result[i] =
          graph()->NewNode(machine()->BitcastFloat32ToInt32(), replacements[i]);
    } else {
      result[i] = nullptr;
    }
  }
}

void SimdScalarLowering::Int64ToInt32(Node** replacements, Node** result) {
  const int num_ints = sizeof(int64_t) / sizeof(int32_t);
  const int bit_size = sizeof(int32_t) * 8;
  const Operator* truncate = machine()->TruncateInt64ToInt32();

  for (int i = 0; i < kNumLanes64; i++) {
    if (replacements[i] != nullptr) {
      for (int j = 0; j < num_ints; j++) {
        result[num_ints * i + j] = graph()->NewNode(
            truncate, graph()->NewNode(machine()->Word64Sar(), replacements[i],
                                       mcgraph_->Int32Constant(j * bit_size)));
      }
    } else {
      for (int j = 0; j < num_ints; j++) {
        result[num_ints * i + j] = nullptr;
      }
    }
  }
}

template <typename T>
void SimdScalarLowering::Int32ToSmallerInt(Node** replacements, Node** result) {
  const int num_ints = sizeof(int32_t) / sizeof(T);
  const int bit_size = sizeof(T) * 8;
  const Operator* sign_extend;
  switch (sizeof(T)) {
    case 1:
      sign_extend = machine()->SignExtendWord8ToInt32();
      break;
    case 2:
      sign_extend = machine()->SignExtendWord16ToInt32();
      break;
    default:
      UNREACHABLE();
  }

  for (int i = 0; i < kNumLanes32; i++) {
    if (replacements[i] != nullptr) {
      for (int j = 0; j < num_ints; j++) {
        result[num_ints * i + j] = graph()->NewNode(
            sign_extend,
            graph()->NewNode(machine()->Word32Shr(), replacements[i],
                             mcgraph_->Int32Constant(j * bit_size)));
      }
    } else {
      for (int j = 0; j < num_ints; j++) {
        result[num_ints * i + j] = nullptr;
      }
    }
  }
}

template <typename T>
void SimdScalarLowering::SmallerIntToInt32(Node** replacements, Node** result) {
  const int num_ints = sizeof(int32_t) / sizeof(T);
  const int bit_size = sizeof(T) * 8;
  const int bit_mask = (1 << bit_size) - 1;

  for (int i = 0; i < kNumLanes32; ++i) {
    result[i] = mcgraph_->Int32Constant(0);
    for (int j = 0; j < num_ints; j++) {
      if (replacements[num_ints * i + j] != nullptr) {
        Node* clean_bits = graph()->NewNode(machine()->Word32And(),
                                            replacements[num_ints * i + j],
                                            mcgraph_->Int32Constant(bit_mask));
        Node* shift = graph()->NewNode(machine()->Word32Shl(), clean_bits,
                                       mcgraph_->Int32Constant(j * bit_size));
        result[i] = graph()->NewNode(machine()->Word32Or(), result[i], shift);
      }
    }
  }
}

void SimdScalarLowering::Int32ToInt64(Node** replacements, Node** result) {
  const int num_ints = sizeof(int64_t) / sizeof(int32_t);

  for (int i = 0; i < kNumLanes64; i++) {
    Node* i64 = graph()->NewNode(machine()->ChangeUint32ToUint64(),
                                 replacements[num_ints * i + 1]);
    Node* high = graph()->NewNode(machine()->Word64Shl(), i64,
                                  mcgraph_->Int32Constant(32));
    Node* i64_low = graph()->NewNode(machine()->ChangeUint32ToUint64(),
                                     replacements[num_ints * i]);
    result[i] = graph()->NewNode(machine()->Word64Or(), high, i64_low);
  }
}

Node** SimdScalarLowering::GetReplacementsWithType(Node* node, SimdType type) {
  // Operations like extract lane, bitmask, any_true, all_true replaces a SIMD
  // node with a scalar. Those won't be correctly handled here. They should be
  // special cased and replaced with the appropriate scalar.
  DCHECK_LT(1, ReplacementCount(node));

  Node** replacements = GetReplacements(node);
  if (type == ReplacementType(node)) {
    return replacements;
  }

  int num_lanes = NumLanes(type);
  Node** result = zone()->NewArray<Node*>(num_lanes);

  switch (type) {
    case SimdType::kInt64x2: {
      switch (ReplacementType(node)) {
        case SimdType::kInt64x2: {
          UNREACHABLE();
        }
        case SimdType::kInt32x4: {
          Int32ToInt64(replacements, result);
          break;
        }
        case SimdType::kInt16x8: {
          Node** to_int32 = zone()->NewArray<Node*>(kNumLanes32);
          SmallerIntToInt32<int16_t>(replacements, to_int32);
          Int32ToInt64(to_int32, result);
          break;
        }
        case SimdType::kInt8x16: {
          Node** to_int32 = zone()->NewArray<Node*>(kNumLanes32);
          SmallerIntToInt32<int8_t>(replacements, to_int32);
          Int32ToInt64(to_int32, result);
          break;
        }
        case SimdType::kFloat64x2: {
          Float64ToInt64(replacements, result);
          break;
        }
        case SimdType::kFloat32x4: {
          Node** to_int32 = zone()->NewArray<Node*>(kNumLanes32);
          Float32ToInt32(replacements, to_int32);
          Int32ToInt64(to_int32, result);
          break;
        }
      }
      break;
    }
    case SimdType::kInt32x4: {
      switch (ReplacementType(node)) {
        case SimdType::kInt64x2: {
          Int64ToInt32(replacements, result);
          break;
        }
        case SimdType::kInt32x4: {
          UNREACHABLE();
        }
        case SimdType::kInt16x8: {
          SmallerIntToInt32<int16_t>(replacements, result);
          break;
        }
        case SimdType::kInt8x16: {
          SmallerIntToInt32<int8_t>(replacements, result);
          break;
        }
        case SimdType::kFloat64x2: {
          Node** float64_to_int64 = zone()->NewArray<Node*>(kNumLanes64);
          Float64ToInt64(replacements, float64_to_int64);
          Int64ToInt32(float64_to_int64, result);
          break;
        }
        case SimdType::kFloat32x4: {
          Float32ToInt32(replacements, result);
          break;
        }
      }
      break;
    }
    case SimdType::kInt16x8: {
      switch (ReplacementType(node)) {
        case SimdType::kInt64x2: {
          Node** to_int32 = zone()->NewArray<Node*>(kNumLanes32);
          Int64ToInt32(replacements, to_int32);
          Int32ToSmallerInt<int16_t>(to_int32, result);
          break;
        }
        case SimdType::kInt32x4: {
          Int32ToSmallerInt<int16_t>(replacements, result);
          break;
        }
        case SimdType::kInt16x8: {
          UNREACHABLE();
        }
        case SimdType::kInt8x16: {
          Node** to_int32 = zone()->NewArray<Node*>(kNumLanes32);
          SmallerIntToInt32<int8_t>(replacements, to_int32);
          Int32ToSmallerInt<int16_t>(to_int32, result);
          break;
        }
        case SimdType::kFloat64x2: {
          Node** to_int64 = zone()->NewArray<Node*>(kNumLanes64);
          Node** to_int32 = zone()->NewArray<Node*>(kNumLanes32);
          Float64ToInt64(replacements, to_int64);
          Int64ToInt32(to_int64, to_int32);
          Int32ToSmallerInt<int16_t>(to_int32, result);
          break;
        }
        case SimdType::kFloat32x4: {
          Node** float32_to_int32 = zone()->NewArray<Node*>(kNumLanes32);
          Float32ToInt32(replacements, float32_to_int32);
          Int32ToSmallerInt<int16_t>(float32_to_int32, result);
          break;
        }
      }
      break;
    }
    case SimdType::kInt8x16: {
      switch (ReplacementType(node)) {
        case SimdType::kInt64x2: {
          Node** int64_to_int32 = zone()->NewArray<Node*>(kNumLanes32);
          Int64ToInt32(replacements, int64_to_int32);
          Int32ToSmallerInt<int8_t>(int64_to_int32, result);
          break;
        }
        case SimdType::kInt32x4: {
          Int32ToSmallerInt<int8_t>(replacements, result);
          break;
        }
        case SimdType::kInt16x8: {
          Node** int16_to_int32 = zone()->NewArray<Node*>(kNumLanes32);
          SmallerIntToInt32<int16_t>(replacements, int16_to_int32);
          Int32ToSmallerInt<int8_t>(int16_to_int32, result);
          break;
        }
        case SimdType::kInt8x16: {
          UNREACHABLE();
        }
        case SimdType::kFloat64x2: {
          Node** to_int64 = zone()->NewArray<Node*>(kNumLanes64);
          Node** to_int32 = zone()->NewArray<Node*>(kNumLanes32);
          Float64ToInt64(replacements, to_int64);
          Int64ToInt32(to_int64, to_int32);
          Int32ToSmallerInt<int8_t>(to_int32, result);
          break;
        }
        case SimdType::kFloat32x4: {
          Node** float32_to_int32 = zone()->NewArray<Node*>(kNumLanes32);
          Float32ToInt32(replacements, float32_to_int32);
          Int32ToSmallerInt<int8_t>(float32_to_int32, result);
          break;
        }
      }
      break;
    }
    case SimdType::kFloat64x2: {
      switch (ReplacementType(node)) {
        case SimdType::kInt64x2: {
          Int64ToFloat64(replacements, result);
          break;
        }
        case SimdType::kInt32x4: {
          Node** int32_to_int64 = zone()->NewArray<Node*>(kNumLanes64);
          Int32ToInt64(replacements, int32_to_int64);
          Int64ToFloat64(int32_to_int64, result);
          break;
        }
        case SimdType::kInt16x8: {
          Node** to_int32 = zone()->NewArray<Node*>(kNumLanes32);
          Node** to_int64 = zone()->NewArray<Node*>(kNumLanes64);
          SmallerIntToInt32<int16_t>(replacements, to_int32);
          Int32ToInt64(to_int32, to_int64);
          Int64ToFloat64(to_int64, result);
          break;
        }
        case SimdType::kInt8x16: {
          Node** to_int32 = zone()->NewArray<Node*>(kNumLanes32);
          Node** to_int64 = zone()->NewArray<Node*>(kNumLanes64);
          SmallerIntToInt32<int8_t>(replacements, to_int32);
          Int32ToInt64(to_int32, to_int64);
          Int64ToFloat64(to_int64, result);
          break;
        }
        case SimdType::kFloat64x2: {
          UNREACHABLE();
        }
        case SimdType::kFloat32x4: {
          Node** to_int32 = zone()->NewArray<Node*>(kNumLanes32);
          Node** to_int64 = zone()->NewArray<Node*>(kNumLanes64);
          Float32ToInt32(replacements, to_int32);
          Int32ToInt64(to_int32, to_int64);
          Int64ToFloat64(to_int64, result);
          break;
        }
      }
      break;
    }
    case SimdType::kFloat32x4: {
      switch (ReplacementType(node)) {
        case SimdType::kInt64x2: {
          Node** to_int32 = zone()->NewArray<Node*>(kNumLanes32);
          Int64ToInt32(replacements, to_int32);
          Int32ToFloat32(to_int32, result);
          break;
        }
        case SimdType::kInt32x4: {
          Int32ToFloat32(replacements, result);
          break;
        }
        case SimdType::kInt16x8: {
          Node** to_int32 = zone()->NewArray<Node*>(kNumLanes32);
          SmallerIntToInt32<int16_t>(replacements, to_int32);
          Int32ToFloat32(to_int32, result);
          break;
        }
        case SimdType::kInt8x16: {
          SmallerIntToInt32<int8_t>(replacements, result);
          Int32ToFloat32(result, result);
          break;
        }
        case SimdType::kFloat64x2: {
          Node** float64_to_int64 = zone()->NewArray<Node*>(kNumLanes64);
          Node** int64_to_int32 = zone()->NewArray<Node*>(kNumLanes32);
          Float64ToInt64(replacements, float64_to_int64);
          Int64ToInt32(float64_to_int64, int64_to_int32);
          Int32ToFloat32(int64_to_int32, result);
          break;
        }
        case SimdType::kFloat32x4: {
          UNREACHABLE();
        }
      }
      break;
    }
  }
  return result;
}

void SimdScalarLowering::PreparePhiReplacement(Node* phi) {
  MachineRepresentation rep = PhiRepresentationOf(phi->op());
  if (rep == MachineRepresentation::kSimd128) {
    // We have to create the replacements for a phi node before we actually
    // lower the phi to break potential cycles in the graph. The replacements of
    // input nodes do not exist yet, so we use a placeholder node to pass the
    // graph verifier.
    int value_count = phi->op()->ValueInputCount();
    SimdType type = ReplacementType(phi);
    int num_lanes = NumLanes(type);
    Node*** inputs_rep = zone()->NewArray<Node**>(num_lanes);
    for (int i = 0; i < num_lanes; ++i) {
      inputs_rep[i] = zone()->NewArray<Node*>(value_count + 1);
      inputs_rep[i][value_count] = NodeProperties::GetControlInput(phi, 0);
    }
    for (int i = 0; i < value_count; ++i) {
      for (int j = 0; j < num_lanes; ++j) {
        inputs_rep[j][i] = placeholder_;
      }
    }
    Node** rep_nodes = zone()->NewArray<Node*>(num_lanes);
    for (int i = 0; i < num_lanes; ++i) {
      rep_nodes[i] = graph()->NewNode(
          common()->Phi(MachineTypeFrom(type).representation(), value_count),
          value_count + 1, inputs_rep[i], false);
    }
    ReplaceNode(phi, rep_nodes, num_lanes);
  }
}
}  // namespace compiler
}  // namespace internal
}  // namespace v8
