18640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org// Copyright 2014 the V8 project authors. All rights reserved.
28640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org// Use of this source code is governed by a BSD-style license that can be
38640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org// found in the LICENSE file.
48640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org
5ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org#include "src/compiler/instruction-selector-unittest.h"
68640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org
79aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org#include "src/compiler/compiler-test-utils.h"
85e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org#include "src/flags.h"
95e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
108640107360766c74218cf16d51b714b1f2138839machenbach@chromium.orgnamespace v8 {
118640107360766c74218cf16d51b714b1f2138839machenbach@chromium.orgnamespace internal {
128640107360766c74218cf16d51b714b1f2138839machenbach@chromium.orgnamespace compiler {
138640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org
14e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.orgnamespace {
15e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
16e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.orgtypedef RawMachineAssembler::Label MLabel;
17e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
18e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org}  // namespace
19e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
20e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
215e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.orgInstructionSelectorTest::InstructionSelectorTest() : rng_(FLAG_random_seed) {}
225e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
235e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
249aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.orgInstructionSelectorTest::~InstructionSelectorTest() {}
259aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org
269aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org
278640107360766c74218cf16d51b714b1f2138839machenbach@chromium.orgInstructionSelectorTest::Stream InstructionSelectorTest::StreamBuilder::Build(
288640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org    InstructionSelector::Features features,
298640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org    InstructionSelectorTest::StreamBuilderMode mode) {
308640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  Schedule* schedule = Export();
315e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  if (FLAG_trace_turbo) {
325e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    OFStream out(stdout);
335e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    out << "=== Schedule before instruction selection ===" << endl << *schedule;
345e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  }
358640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  EXPECT_NE(0, graph()->NodeCount());
368640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  CompilationInfo info(test_->isolate(), test_->zone());
378640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  Linkage linkage(&info, call_descriptor());
388640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  InstructionSequence sequence(&linkage, graph(), schedule);
398640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  SourcePositionTable source_position_table(graph());
408640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  InstructionSelector selector(&sequence, &source_position_table, features);
418640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  selector.SelectInstructions();
428640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  if (FLAG_trace_turbo) {
438640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org    OFStream out(stdout);
445e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    out << "=== Code sequence after instruction selection ===" << endl
458640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org        << sequence;
468640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  }
478640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  Stream s;
48e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  std::set<int> virtual_registers;
498640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  for (InstructionSequence::const_iterator i = sequence.begin();
508640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org       i != sequence.end(); ++i) {
518640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org    Instruction* instr = *i;
528640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org    if (instr->opcode() < 0) continue;
538640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org    if (mode == kTargetInstructions) {
548640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org      switch (instr->arch_opcode()) {
558640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org#define CASE(Name) \
568640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  case k##Name:    \
578640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org    break;
588640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org        TARGET_ARCH_OPCODE_LIST(CASE)
598640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org#undef CASE
608640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org        default:
618640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org          continue;
628640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org      }
638640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org    }
645fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org    if (mode == kAllExceptNopInstructions && instr->arch_opcode() == kArchNop) {
655fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org      continue;
665fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org    }
678640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org    for (size_t i = 0; i < instr->OutputCount(); ++i) {
688640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org      InstructionOperand* output = instr->OutputAt(i);
698640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org      EXPECT_NE(InstructionOperand::IMMEDIATE, output->kind());
708640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org      if (output->IsConstant()) {
718640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org        s.constants_.insert(std::make_pair(
728640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org            output->index(), sequence.GetConstant(output->index())));
73e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org        virtual_registers.insert(output->index());
74e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org      } else if (output->IsUnallocated()) {
75e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org        virtual_registers.insert(
76e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org            UnallocatedOperand::cast(output)->virtual_register());
778640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org      }
788640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org    }
798640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org    for (size_t i = 0; i < instr->InputCount(); ++i) {
808640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org      InstructionOperand* input = instr->InputAt(i);
818640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org      EXPECT_NE(InstructionOperand::CONSTANT, input->kind());
828640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org      if (input->IsImmediate()) {
838640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org        s.immediates_.insert(std::make_pair(
848640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org            input->index(), sequence.GetImmediate(input->index())));
85e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org      } else if (input->IsUnallocated()) {
86e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org        virtual_registers.insert(
87e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org            UnallocatedOperand::cast(input)->virtual_register());
888640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org      }
898640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org    }
908640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org    s.instructions_.push_back(instr);
918640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  }
92e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  for (std::set<int>::const_iterator i = virtual_registers.begin();
93e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org       i != virtual_registers.end(); ++i) {
94e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org    int virtual_register = *i;
95e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org    if (sequence.IsDouble(virtual_register)) {
96e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org      EXPECT_FALSE(sequence.IsReference(virtual_register));
97e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org      s.doubles_.insert(virtual_register);
98e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org    }
99e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org    if (sequence.IsReference(virtual_register)) {
100e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org      EXPECT_FALSE(sequence.IsDouble(virtual_register));
101e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org      s.references_.insert(virtual_register);
102e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org    }
103e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  }
104ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  for (int i = 0; i < sequence.GetFrameStateDescriptorCount(); i++) {
105ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org    s.deoptimization_entries_.push_back(sequence.GetFrameStateDescriptor(
106ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org        InstructionSequence::StateId::FromInt(i)));
1075fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org  }
1088640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  return s;
1098640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org}
1108640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org
1118640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org
1127dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org// -----------------------------------------------------------------------------
1137dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org// Return.
1147dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org
1157dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org
1165e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.orgTARGET_TEST_F(InstructionSelectorTest, ReturnParameter) {
1175e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  StreamBuilder m(this, kMachInt32, kMachInt32);
1188640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  m.Return(m.Parameter(0));
1198640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  Stream s = m.Build(kAllInstructions);
1208640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  ASSERT_EQ(2U, s.size());
1218640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  EXPECT_EQ(kArchNop, s[0]->arch_opcode());
1228640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  ASSERT_EQ(1U, s[0]->OutputCount());
1238640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  EXPECT_EQ(kArchRet, s[1]->arch_opcode());
1248640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  EXPECT_EQ(1U, s[1]->InputCount());
1258640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org}
1268640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org
1278640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org
1285e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.orgTARGET_TEST_F(InstructionSelectorTest, ReturnZero) {
1295e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  StreamBuilder m(this, kMachInt32);
1308640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  m.Return(m.Int32Constant(0));
1318640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  Stream s = m.Build(kAllInstructions);
1328640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  ASSERT_EQ(2U, s.size());
1338640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  EXPECT_EQ(kArchNop, s[0]->arch_opcode());
1348640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  ASSERT_EQ(1U, s[0]->OutputCount());
1358640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  EXPECT_EQ(InstructionOperand::CONSTANT, s[0]->OutputAt(0)->kind());
1368640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  EXPECT_EQ(0, s.ToInt32(s[0]->OutputAt(0)));
1378640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  EXPECT_EQ(kArchRet, s[1]->arch_opcode());
1388640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  EXPECT_EQ(1U, s[1]->InputCount());
1398640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org}
1408640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org
1417dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org
1427dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org// -----------------------------------------------------------------------------
1437dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org// Conversions.
1447dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org
1457dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org
1467dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.orgTARGET_TEST_F(InstructionSelectorTest, TruncateFloat64ToInt32WithParameter) {
1477dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org  StreamBuilder m(this, kMachInt32, kMachFloat64);
1487dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org  m.Return(m.TruncateFloat64ToInt32(m.Parameter(0)));
1497dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org  Stream s = m.Build(kAllInstructions);
1507dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org  ASSERT_EQ(3U, s.size());
1517dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org  EXPECT_EQ(kArchNop, s[0]->arch_opcode());
1527dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org  EXPECT_EQ(kArchTruncateDoubleToI, s[1]->arch_opcode());
1537dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org  EXPECT_EQ(1U, s[1]->InputCount());
1547dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org  EXPECT_EQ(1U, s[1]->OutputCount());
1557dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org  EXPECT_EQ(kArchRet, s[2]->arch_opcode());
1567dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org}
1577dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org
158e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
159e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org// -----------------------------------------------------------------------------
160e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org// Parameters.
161e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
162e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
163e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.orgTARGET_TEST_F(InstructionSelectorTest, DoubleParameter) {
164e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  StreamBuilder m(this, kMachFloat64, kMachFloat64);
165e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  Node* param = m.Parameter(0);
166e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  m.Return(param);
167e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  Stream s = m.Build(kAllInstructions);
168e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  EXPECT_TRUE(s.IsDouble(param->id()));
169e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org}
170e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
171e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
172e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.orgTARGET_TEST_F(InstructionSelectorTest, ReferenceParameter) {
173e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  StreamBuilder m(this, kMachAnyTagged, kMachAnyTagged);
174e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  Node* param = m.Parameter(0);
175e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  m.Return(param);
176e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  Stream s = m.Build(kAllInstructions);
177e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  EXPECT_TRUE(s.IsReference(param->id()));
178e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org}
179e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
180e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
181e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org// -----------------------------------------------------------------------------
182e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org// Finish.
183e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
184e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
18542ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.orgTARGET_TEST_F(InstructionSelectorTest, Finish) {
1869aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  StreamBuilder m(this, kMachAnyTagged, kMachAnyTagged);
187e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  Node* param = m.Parameter(0);
188e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  Node* finish = m.NewNode(m.common()->Finish(1), param, m.graph()->start());
189e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  m.Return(finish);
190e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  Stream s = m.Build(kAllInstructions);
191e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  ASSERT_EQ(3U, s.size());
192e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  EXPECT_EQ(kArchNop, s[0]->arch_opcode());
193e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  ASSERT_EQ(1U, s[0]->OutputCount());
194e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  ASSERT_TRUE(s[0]->Output()->IsUnallocated());
195fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org  EXPECT_EQ(param->id(), s.ToVreg(s[0]->Output()));
196e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  EXPECT_EQ(kArchNop, s[1]->arch_opcode());
197e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  ASSERT_EQ(1U, s[1]->InputCount());
198e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  ASSERT_TRUE(s[1]->InputAt(0)->IsUnallocated());
199fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org  EXPECT_EQ(param->id(), s.ToVreg(s[1]->InputAt(0)));
200e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  ASSERT_EQ(1U, s[1]->OutputCount());
201e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  ASSERT_TRUE(s[1]->Output()->IsUnallocated());
202e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  EXPECT_TRUE(UnallocatedOperand::cast(s[1]->Output())->HasSameAsInputPolicy());
203fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org  EXPECT_EQ(finish->id(), s.ToVreg(s[1]->Output()));
20442ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org  EXPECT_TRUE(s.IsReference(finish->id()));
205e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org}
206e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
207e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
208e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org// -----------------------------------------------------------------------------
2099aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org// Phi.
210e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
211e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
212e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.orgtypedef InstructionSelectorTestWithParam<MachineType>
213e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org    InstructionSelectorPhiTest;
214e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
215e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
21642ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.orgTARGET_TEST_P(InstructionSelectorPhiTest, Doubleness) {
217e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  const MachineType type = GetParam();
218e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  StreamBuilder m(this, type, type, type);
219e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  Node* param0 = m.Parameter(0);
220e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  Node* param1 = m.Parameter(1);
221e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  MLabel a, b, c;
222e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  m.Branch(m.Int32Constant(0), &a, &b);
223e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  m.Bind(&a);
224e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  m.Goto(&c);
225e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  m.Bind(&b);
226e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  m.Goto(&c);
227e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  m.Bind(&c);
22842ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org  Node* phi = m.Phi(type, param0, param1);
229e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  m.Return(phi);
230e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  Stream s = m.Build(kAllInstructions);
231e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  EXPECT_EQ(s.IsDouble(phi->id()), s.IsDouble(param0->id()));
232e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  EXPECT_EQ(s.IsDouble(phi->id()), s.IsDouble(param1->id()));
233e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org}
234e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
235e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
23642ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.orgTARGET_TEST_P(InstructionSelectorPhiTest, Referenceness) {
237e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  const MachineType type = GetParam();
238e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  StreamBuilder m(this, type, type, type);
239e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  Node* param0 = m.Parameter(0);
240e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  Node* param1 = m.Parameter(1);
241e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  MLabel a, b, c;
242e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  m.Branch(m.Int32Constant(1), &a, &b);
243e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  m.Bind(&a);
244e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  m.Goto(&c);
245e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  m.Bind(&b);
246e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  m.Goto(&c);
247e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  m.Bind(&c);
24842ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org  Node* phi = m.Phi(type, param0, param1);
249e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  m.Return(phi);
250e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  Stream s = m.Build(kAllInstructions);
251e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  EXPECT_EQ(s.IsReference(phi->id()), s.IsReference(param0->id()));
252e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  EXPECT_EQ(s.IsReference(phi->id()), s.IsReference(param1->id()));
253e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org}
254e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
255e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
256e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.orgINSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorPhiTest,
257e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org                        ::testing::Values(kMachFloat64, kMachInt8, kMachUint8,
258e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org                                          kMachInt16, kMachUint16, kMachInt32,
259e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org                                          kMachUint32, kMachInt64, kMachUint64,
260e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org                                          kMachPtr, kMachAnyTagged));
261e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
262e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
263e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org// -----------------------------------------------------------------------------
264e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org// ValueEffect.
265e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
266e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
267e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.orgTARGET_TEST_F(InstructionSelectorTest, ValueEffect) {
268e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  StreamBuilder m1(this, kMachInt32, kMachPtr);
269e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  Node* p1 = m1.Parameter(0);
270e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  m1.Return(m1.Load(kMachInt32, p1, m1.Int32Constant(0)));
271e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  Stream s1 = m1.Build(kAllInstructions);
272e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  StreamBuilder m2(this, kMachInt32, kMachPtr);
273e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  Node* p2 = m2.Parameter(0);
274e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  m2.Return(m2.NewNode(m2.machine()->Load(kMachInt32), p2, m2.Int32Constant(0),
275e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org                       m2.NewNode(m2.common()->ValueEffect(1), p2)));
276e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  Stream s2 = m2.Build(kAllInstructions);
277e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  EXPECT_LE(3U, s1.size());
278e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  ASSERT_EQ(s1.size(), s2.size());
279e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  TRACED_FORRANGE(size_t, i, 0, s1.size() - 1) {
280e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org    const Instruction* i1 = s1[i];
281e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org    const Instruction* i2 = s2[i];
282e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org    EXPECT_EQ(i1->arch_opcode(), i2->arch_opcode());
283e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org    EXPECT_EQ(i1->InputCount(), i2->InputCount());
284e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org    EXPECT_EQ(i1->OutputCount(), i2->OutputCount());
285e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  }
286e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org}
287e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
2885fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org
2895fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org// -----------------------------------------------------------------------------
2905fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org// Calls with deoptimization.
291d71b62088ad094b1187c06c92d1f27fab56aaddbmachenbach@chromium.orgTARGET_TEST_F(InstructionSelectorTest, CallJSFunctionWithDeopt) {
2929aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  StreamBuilder m(this, kMachAnyTagged, kMachAnyTagged, kMachAnyTagged,
2939aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org                  kMachAnyTagged);
2945fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org
2955fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org  BailoutId bailout_id(42);
2965fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org
2975fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org  Node* function_node = m.Parameter(0);
2985fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org  Node* receiver = m.Parameter(1);
2999aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  Node* context = m.Parameter(2);
3005fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org
3015fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org  Node* parameters = m.NewNode(m.common()->StateValues(1), m.Int32Constant(1));
3025fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org  Node* locals = m.NewNode(m.common()->StateValues(0));
3035fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org  Node* stack = m.NewNode(m.common()->StateValues(0));
304ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  Node* context_dummy = m.Int32Constant(0);
3055fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org
306a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  Node* state_node = m.NewNode(
307a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org      m.common()->FrameState(JS_FRAME, bailout_id, kPushOutput), parameters,
308a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org      locals, stack, context_dummy, m.UndefinedConstant());
3099aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  Node* call = m.CallJS0(function_node, receiver, context, state_node);
310ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  m.Return(call);
3115fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org
3125fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org  Stream s = m.Build(kAllExceptNopInstructions);
3135fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org
3145fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org  // Skip until kArchCallJSFunction.
3155fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org  size_t index = 0;
3165fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org  for (; index < s.size() && s[index]->arch_opcode() != kArchCallJSFunction;
3175fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org       index++) {
3185fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org  }
319ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  // Now we should have two instructions: call and return.
320ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  ASSERT_EQ(index + 2, s.size());
3215fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org
3225fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org  EXPECT_EQ(kArchCallJSFunction, s[index++]->arch_opcode());
3235fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org  EXPECT_EQ(kArchRet, s[index++]->arch_opcode());
324ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org
325ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  // TODO(jarin) Check deoptimization table.
3265fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org}
3275fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org
3285fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org
329d71b62088ad094b1187c06c92d1f27fab56aaddbmachenbach@chromium.orgTARGET_TEST_F(InstructionSelectorTest, CallFunctionStubWithDeopt) {
3305fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org  StreamBuilder m(this, kMachAnyTagged, kMachAnyTagged, kMachAnyTagged,
3315fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org                  kMachAnyTagged);
3325fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org
3335fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org  BailoutId bailout_id_before(42);
3345fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org
3355fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org  // Some arguments for the call node.
3365fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org  Node* function_node = m.Parameter(0);
3375fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org  Node* receiver = m.Parameter(1);
3385fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org  Node* context = m.Int32Constant(1);  // Context is ignored.
3395fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org
3405fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org  // Build frame state for the state before the call.
3415fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org  Node* parameters = m.NewNode(m.common()->StateValues(1), m.Int32Constant(43));
3425fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org  Node* locals = m.NewNode(m.common()->StateValues(1), m.Int32Constant(44));
3435fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org  Node* stack = m.NewNode(m.common()->StateValues(1), m.Int32Constant(45));
3449aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org
345ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  Node* context_sentinel = m.Int32Constant(0);
3469aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  Node* frame_state_before = m.NewNode(
347a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org      m.common()->FrameState(JS_FRAME, bailout_id_before, kPushOutput),
348a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org      parameters, locals, stack, context_sentinel, m.UndefinedConstant());
3495fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org
3505fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org  // Build the call.
351ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  Node* call = m.CallFunctionStub0(function_node, receiver, context,
352ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                                   frame_state_before, CALL_AS_METHOD);
3535fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org
3545fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org  m.Return(call);
3555fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org
3565fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org  Stream s = m.Build(kAllExceptNopInstructions);
3575fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org
3585fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org  // Skip until kArchCallJSFunction.
3595fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org  size_t index = 0;
3605fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org  for (; index < s.size() && s[index]->arch_opcode() != kArchCallCodeObject;
3615fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org       index++) {
3625fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org  }
363ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  // Now we should have two instructions: call, return.
364ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  ASSERT_EQ(index + 2, s.size());
3655fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org
3665fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org  // Check the call instruction
3675fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org  const Instruction* call_instr = s[index++];
3685fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org  EXPECT_EQ(kArchCallCodeObject, call_instr->arch_opcode());
3695fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org  size_t num_operands =
3705fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org      1 +  // Code object.
3715fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org      1 +
372ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org      4 +  // Frame state deopt id + one input for each value in frame state.
3735fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org      1 +  // Function.
374ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org      1;   // Context.
3755fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org  ASSERT_EQ(num_operands, call_instr->InputCount());
3765fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org
3775fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org  // Code object.
3785fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org  EXPECT_TRUE(call_instr->InputAt(0)->IsImmediate());
3795fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org
3805fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org  // Deoptimization id.
3815fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org  int32_t deopt_id_before = s.ToInt32(call_instr->InputAt(1));
382ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  FrameStateDescriptor* desc_before =
383ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org      s.GetFrameStateDescriptor(deopt_id_before);
3845fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org  EXPECT_EQ(bailout_id_before, desc_before->bailout_id());
385ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  EXPECT_EQ(kPushOutput, desc_before->state_combine());
386a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  EXPECT_EQ(1u, desc_before->parameters_count());
387a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  EXPECT_EQ(1u, desc_before->locals_count());
388a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  EXPECT_EQ(1u, desc_before->stack_count());
3895fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org  EXPECT_EQ(43, s.ToInt32(call_instr->InputAt(2)));
390ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  EXPECT_EQ(0, s.ToInt32(call_instr->InputAt(3)));
391ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  EXPECT_EQ(44, s.ToInt32(call_instr->InputAt(4)));
392ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  EXPECT_EQ(45, s.ToInt32(call_instr->InputAt(5)));
3935fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org
3945fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org  // Function.
395ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  EXPECT_EQ(function_node->id(), s.ToVreg(call_instr->InputAt(6)));
3965fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org  // Context.
397ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  EXPECT_EQ(context->id(), s.ToVreg(call_instr->InputAt(7)));
3985fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org
3995fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org  EXPECT_EQ(kArchRet, s[index++]->arch_opcode());
4005fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org
4015fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org  EXPECT_EQ(index, s.size());
4025fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org}
4035fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org
4049aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org
4059aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.orgTARGET_TEST_F(InstructionSelectorTest,
4069aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org              CallFunctionStubDeoptRecursiveFrameState) {
4079aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  StreamBuilder m(this, kMachAnyTagged, kMachAnyTagged, kMachAnyTagged,
4089aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org                  kMachAnyTagged);
4099aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org
4109aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  BailoutId bailout_id_before(42);
4119aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  BailoutId bailout_id_parent(62);
4129aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org
4139aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  // Some arguments for the call node.
4149aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  Node* function_node = m.Parameter(0);
4159aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  Node* receiver = m.Parameter(1);
4169aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  Node* context = m.Int32Constant(66);
4179aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org
4189aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  // Build frame state for the state before the call.
4199aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  Node* parameters = m.NewNode(m.common()->StateValues(1), m.Int32Constant(63));
4209aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  Node* locals = m.NewNode(m.common()->StateValues(1), m.Int32Constant(64));
4219aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  Node* stack = m.NewNode(m.common()->StateValues(1), m.Int32Constant(65));
422a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  Node* frame_state_parent = m.NewNode(
423a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org      m.common()->FrameState(JS_FRAME, bailout_id_parent, kIgnoreOutput),
424a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org      parameters, locals, stack, context, m.UndefinedConstant());
4259aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org
4269aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  Node* context2 = m.Int32Constant(46);
4279aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  Node* parameters2 =
4289aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org      m.NewNode(m.common()->StateValues(1), m.Int32Constant(43));
4299aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  Node* locals2 = m.NewNode(m.common()->StateValues(1), m.Int32Constant(44));
4309aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  Node* stack2 = m.NewNode(m.common()->StateValues(1), m.Int32Constant(45));
431a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  Node* frame_state_before = m.NewNode(
432a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org      m.common()->FrameState(JS_FRAME, bailout_id_before, kPushOutput),
433a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org      parameters2, locals2, stack2, context2, frame_state_parent);
4349aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org
4359aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  // Build the call.
4369aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  Node* call = m.CallFunctionStub0(function_node, receiver, context2,
4379aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org                                   frame_state_before, CALL_AS_METHOD);
4389aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org
4399aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  m.Return(call);
4409aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org
4419aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  Stream s = m.Build(kAllExceptNopInstructions);
4429aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org
4439aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  // Skip until kArchCallJSFunction.
4449aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  size_t index = 0;
4459aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  for (; index < s.size() && s[index]->arch_opcode() != kArchCallCodeObject;
4469aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org       index++) {
4479aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  }
4489aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  // Now we should have three instructions: call, return.
4499aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  EXPECT_EQ(index + 2, s.size());
4509aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org
4519aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  // Check the call instruction
4529aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  const Instruction* call_instr = s[index++];
4539aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  EXPECT_EQ(kArchCallCodeObject, call_instr->arch_opcode());
4549aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  size_t num_operands =
4559aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org      1 +  // Code object.
4569aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org      1 +  // Frame state deopt id
4579aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org      4 +  // One input for each value in frame state + context.
4589aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org      4 +  // One input for each value in the parent frame state + context.
4599aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org      1 +  // Function.
4609aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org      1;   // Context.
4619aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  EXPECT_EQ(num_operands, call_instr->InputCount());
4629aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  // Code object.
4639aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  EXPECT_TRUE(call_instr->InputAt(0)->IsImmediate());
4649aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org
4659aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  // Deoptimization id.
4669aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  int32_t deopt_id_before = s.ToInt32(call_instr->InputAt(1));
4679aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  FrameStateDescriptor* desc_before =
4689aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org      s.GetFrameStateDescriptor(deopt_id_before);
4699aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  EXPECT_EQ(bailout_id_before, desc_before->bailout_id());
470a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  EXPECT_EQ(1u, desc_before->parameters_count());
471a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  EXPECT_EQ(1u, desc_before->locals_count());
472a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  EXPECT_EQ(1u, desc_before->stack_count());
4739aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  EXPECT_EQ(63, s.ToInt32(call_instr->InputAt(2)));
4749aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  // Context:
4759aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  EXPECT_EQ(66, s.ToInt32(call_instr->InputAt(3)));
4769aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  EXPECT_EQ(64, s.ToInt32(call_instr->InputAt(4)));
4779aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  EXPECT_EQ(65, s.ToInt32(call_instr->InputAt(5)));
4789aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  // Values from parent environment should follow.
4799aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  EXPECT_EQ(43, s.ToInt32(call_instr->InputAt(6)));
4809aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  EXPECT_EQ(46, s.ToInt32(call_instr->InputAt(7)));
4819aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  EXPECT_EQ(44, s.ToInt32(call_instr->InputAt(8)));
4829aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  EXPECT_EQ(45, s.ToInt32(call_instr->InputAt(9)));
4839aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org
4849aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  // Function.
4859aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  EXPECT_EQ(function_node->id(), s.ToVreg(call_instr->InputAt(10)));
4869aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  // Context.
4879aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  EXPECT_EQ(context2->id(), s.ToVreg(call_instr->InputAt(11)));
4889aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  // Continuation.
4899aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org
4909aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  EXPECT_EQ(kArchRet, s[index++]->arch_opcode());
4919aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  EXPECT_EQ(index, s.size());
4929aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org}
4939aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org
4948640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org}  // namespace compiler
4958640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org}  // namespace internal
4968640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org}  // namespace v8
497