Merge V8 5.3.332.45. DO NOT MERGE
Test: Manual
FPIIM-449
Change-Id: Id3254828b068abdea3cb10442e0172a8c9a98e03
(cherry picked from commit 13e2dadd00298019ed862f2b2fc5068bba730bcf)
diff --git a/test/unittests/compiler/arm/instruction-selector-arm-unittest.cc b/test/unittests/compiler/arm/instruction-selector-arm-unittest.cc
index b088d8e..fa03039 100644
--- a/test/unittests/compiler/arm/instruction-selector-arm-unittest.cc
+++ b/test/unittests/compiler/arm/instruction-selector-arm-unittest.cc
@@ -1392,8 +1392,8 @@
EXPECT_EQ(memacc.str_opcode, s[0]->arch_opcode());
EXPECT_EQ(kMode_Offset_RI, s[0]->addressing_mode());
ASSERT_EQ(3U, s[0]->InputCount());
- ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
- EXPECT_EQ(index, s.ToInt32(s[0]->InputAt(1)));
+ ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(2)->kind());
+ EXPECT_EQ(index, s.ToInt32(s[0]->InputAt(2)));
EXPECT_EQ(0U, s[0]->OutputCount());
}
}
@@ -1403,6 +1403,39 @@
InstructionSelectorMemoryAccessTest,
::testing::ValuesIn(kMemoryAccesses));
+TEST_F(InstructionSelectorMemoryAccessTest, LoadWithShiftedIndex) {
+ TRACED_FORRANGE(int, immediate_shift, 1, 31) {
+ StreamBuilder m(this, MachineType::Int32(), MachineType::Pointer(),
+ MachineType::Int32());
+ Node* const index =
+ m.Word32Shl(m.Parameter(1), m.Int32Constant(immediate_shift));
+ m.Return(m.Load(MachineType::Int32(), m.Parameter(0), index));
+ Stream s = m.Build();
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kArmLdr, s[0]->arch_opcode());
+ EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode());
+ EXPECT_EQ(3U, s[0]->InputCount());
+ EXPECT_EQ(1U, s[0]->OutputCount());
+ }
+}
+
+TEST_F(InstructionSelectorMemoryAccessTest, StoreWithShiftedIndex) {
+ TRACED_FORRANGE(int, immediate_shift, 1, 31) {
+ StreamBuilder m(this, MachineType::Int32(), MachineType::Pointer(),
+ MachineType::Int32(), MachineType::Int32());
+ Node* const index =
+ m.Word32Shl(m.Parameter(1), m.Int32Constant(immediate_shift));
+ m.Store(MachineRepresentation::kWord32, m.Parameter(0), index,
+ m.Parameter(2), kNoWriteBarrier);
+ m.Return(m.Int32Constant(0));
+ Stream s = m.Build();
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kArmStr, s[0]->arch_opcode());
+ EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode());
+ EXPECT_EQ(4U, s[0]->InputCount());
+ EXPECT_EQ(0U, s[0]->OutputCount());
+ }
+}
// -----------------------------------------------------------------------------
// Conversions.
@@ -2228,7 +2261,7 @@
MachineType::Int32(), MachineType::Int32());
m.Return(
m.Int32Sub(m.Parameter(0), m.Int32Mul(m.Parameter(1), m.Parameter(2))));
- Stream s = m.Build(MLS);
+ Stream s = m.Build(ARMv7);
ASSERT_EQ(1U, s.size());
EXPECT_EQ(kArmMls, s[0]->arch_opcode());
EXPECT_EQ(1U, s[0]->OutputCount());
@@ -2324,7 +2357,7 @@
StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
MachineType::Int32());
m.Return(m.Int32Mod(m.Parameter(0), m.Parameter(1)));
- Stream s = m.Build(MLS, SUDIV);
+ Stream s = m.Build(ARMv7, SUDIV);
ASSERT_EQ(2U, s.size());
EXPECT_EQ(kArmSdiv, s[0]->arch_opcode());
ASSERT_EQ(1U, s[0]->OutputCount());
@@ -2530,7 +2563,7 @@
StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
MachineType::Int32());
m.Return(m.Uint32Mod(m.Parameter(0), m.Parameter(1)));
- Stream s = m.Build(MLS, SUDIV);
+ Stream s = m.Build(ARMv7, SUDIV);
ASSERT_EQ(2U, s.size());
EXPECT_EQ(kArmUdiv, s[0]->arch_opcode());
ASSERT_EQ(1U, s[0]->OutputCount());
@@ -3026,6 +3059,36 @@
EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
}
+TEST_F(InstructionSelectorTest, Float32Neg) {
+ StreamBuilder m(this, MachineType::Float32(), MachineType::Float32());
+ Node* const p0 = m.Parameter(0);
+ // Don't use m.Float32Neg() as that generates an explicit sub.
+ Node* const n = m.AddNode(m.machine()->Float32Neg().op(), m.Parameter(0));
+ m.Return(n);
+ Stream s = m.Build();
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kArmVnegF32, s[0]->arch_opcode());
+ ASSERT_EQ(1U, s[0]->InputCount());
+ EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+ ASSERT_EQ(1U, s[0]->OutputCount());
+ EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
+}
+
+TEST_F(InstructionSelectorTest, Float64Neg) {
+ StreamBuilder m(this, MachineType::Float64(), MachineType::Float64());
+ Node* const p0 = m.Parameter(0);
+ // Don't use m.Float64Neg() as that generates an explicit sub.
+ Node* const n = m.AddNode(m.machine()->Float64Neg().op(), m.Parameter(0));
+ m.Return(n);
+ Stream s = m.Build();
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kArmVnegF64, s[0]->arch_opcode());
+ ASSERT_EQ(1U, s[0]->InputCount());
+ EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+ ASSERT_EQ(1U, s[0]->OutputCount());
+ EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
+}
+
} // namespace compiler
} // namespace internal
} // namespace v8
diff --git a/test/unittests/compiler/arm64/instruction-selector-arm64-unittest.cc b/test/unittests/compiler/arm64/instruction-selector-arm64-unittest.cc
index 1c638b2..5fc210b 100644
--- a/test/unittests/compiler/arm64/instruction-selector-arm64-unittest.cc
+++ b/test/unittests/compiler/arm64/instruction-selector-arm64-unittest.cc
@@ -184,8 +184,11 @@
{&RawMachineAssembler::Int32AddWithOverflow, "Int32AddWithOverflow",
kArm64Add32, MachineType::Int32()},
{&RawMachineAssembler::Int32SubWithOverflow, "Int32SubWithOverflow",
- kArm64Sub32, MachineType::Int32()}};
-
+ kArm64Sub32, MachineType::Int32()},
+ {&RawMachineAssembler::Int64AddWithOverflow, "Int64AddWithOverflow",
+ kArm64Add, MachineType::Int64()},
+ {&RawMachineAssembler::Int64SubWithOverflow, "Int64SubWithOverflow",
+ kArm64Sub, MachineType::Int64()}};
// ARM64 shift instructions.
const Shift kShiftInstructions[] = {
@@ -1178,7 +1181,6 @@
}
}
-
TEST_F(InstructionSelectorTest, Word32AndBranchWithOneBitMaskOnLeft) {
TRACED_FORRANGE(int, bit, 0, 31) {
uint32_t mask = 1 << bit;
@@ -1261,6 +1263,91 @@
}
}
+TEST_F(InstructionSelectorTest, Word32EqualZeroAndBranchWithOneBitMask) {
+ TRACED_FORRANGE(int, bit, 0, 31) {
+ uint32_t mask = 1 << bit;
+ StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
+ RawMachineLabel a, b;
+ m.Branch(m.Word32Equal(m.Word32And(m.Int32Constant(mask), m.Parameter(0)),
+ m.Int32Constant(0)),
+ &a, &b);
+ m.Bind(&a);
+ m.Return(m.Int32Constant(1));
+ m.Bind(&b);
+ m.Return(m.Int32Constant(0));
+ Stream s = m.Build();
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kArm64TestAndBranch32, s[0]->arch_opcode());
+ EXPECT_EQ(kEqual, s[0]->flags_condition());
+ EXPECT_EQ(4U, s[0]->InputCount());
+ EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
+ EXPECT_EQ(bit, s.ToInt32(s[0]->InputAt(1)));
+ }
+
+ TRACED_FORRANGE(int, bit, 0, 31) {
+ uint32_t mask = 1 << bit;
+ StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
+ RawMachineLabel a, b;
+ m.Branch(
+ m.Word32NotEqual(m.Word32And(m.Int32Constant(mask), m.Parameter(0)),
+ m.Int32Constant(0)),
+ &a, &b);
+ m.Bind(&a);
+ m.Return(m.Int32Constant(1));
+ m.Bind(&b);
+ m.Return(m.Int32Constant(0));
+ Stream s = m.Build();
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kArm64TestAndBranch32, s[0]->arch_opcode());
+ EXPECT_EQ(kNotEqual, s[0]->flags_condition());
+ EXPECT_EQ(4U, s[0]->InputCount());
+ EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
+ EXPECT_EQ(bit, s.ToInt32(s[0]->InputAt(1)));
+ }
+}
+
+TEST_F(InstructionSelectorTest, Word64EqualZeroAndBranchWithOneBitMask) {
+ TRACED_FORRANGE(int, bit, 0, 63) {
+ uint64_t mask = V8_UINT64_C(1) << bit;
+ StreamBuilder m(this, MachineType::Int64(), MachineType::Int64());
+ RawMachineLabel a, b;
+ m.Branch(m.Word64Equal(m.Word64And(m.Int64Constant(mask), m.Parameter(0)),
+ m.Int64Constant(0)),
+ &a, &b);
+ m.Bind(&a);
+ m.Return(m.Int64Constant(1));
+ m.Bind(&b);
+ m.Return(m.Int64Constant(0));
+ Stream s = m.Build();
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kArm64TestAndBranch, s[0]->arch_opcode());
+ EXPECT_EQ(kEqual, s[0]->flags_condition());
+ EXPECT_EQ(4U, s[0]->InputCount());
+ EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
+ EXPECT_EQ(bit, s.ToInt64(s[0]->InputAt(1)));
+ }
+
+ TRACED_FORRANGE(int, bit, 0, 63) {
+ uint64_t mask = V8_UINT64_C(1) << bit;
+ StreamBuilder m(this, MachineType::Int64(), MachineType::Int64());
+ RawMachineLabel a, b;
+ m.Branch(
+ m.Word64NotEqual(m.Word64And(m.Int64Constant(mask), m.Parameter(0)),
+ m.Int64Constant(0)),
+ &a, &b);
+ m.Bind(&a);
+ m.Return(m.Int64Constant(1));
+ m.Bind(&b);
+ m.Return(m.Int64Constant(0));
+ Stream s = m.Build();
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kArm64TestAndBranch, s[0]->arch_opcode());
+ EXPECT_EQ(kNotEqual, s[0]->flags_condition());
+ EXPECT_EQ(4U, s[0]->InputCount());
+ EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
+ EXPECT_EQ(bit, s.ToInt64(s[0]->InputAt(1)));
+ }
+}
TEST_F(InstructionSelectorTest, CompareAgainstZeroAndBranch) {
{
@@ -1298,6 +1385,75 @@
}
}
+TEST_F(InstructionSelectorTest, EqualZeroAndBranch) {
+ {
+ StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
+ RawMachineLabel a, b;
+ Node* p0 = m.Parameter(0);
+ m.Branch(m.Word32Equal(p0, m.Int32Constant(0)), &a, &b);
+ m.Bind(&a);
+ m.Return(m.Int32Constant(1));
+ m.Bind(&b);
+ m.Return(m.Int32Constant(0));
+ Stream s = m.Build();
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kArm64CompareAndBranch32, s[0]->arch_opcode());
+ EXPECT_EQ(kEqual, s[0]->flags_condition());
+ EXPECT_EQ(3U, s[0]->InputCount());
+ EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+ }
+
+ {
+ StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
+ RawMachineLabel a, b;
+ Node* p0 = m.Parameter(0);
+ m.Branch(m.Word32NotEqual(p0, m.Int32Constant(0)), &a, &b);
+ m.Bind(&a);
+ m.Return(m.Int32Constant(1));
+ m.Bind(&b);
+ m.Return(m.Int32Constant(0));
+ Stream s = m.Build();
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kArm64CompareAndBranch32, s[0]->arch_opcode());
+ EXPECT_EQ(kNotEqual, s[0]->flags_condition());
+ EXPECT_EQ(3U, s[0]->InputCount());
+ EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+ }
+
+ {
+ StreamBuilder m(this, MachineType::Int64(), MachineType::Int64());
+ RawMachineLabel a, b;
+ Node* p0 = m.Parameter(0);
+ m.Branch(m.Word64Equal(p0, m.Int64Constant(0)), &a, &b);
+ m.Bind(&a);
+ m.Return(m.Int64Constant(1));
+ m.Bind(&b);
+ m.Return(m.Int64Constant(0));
+ Stream s = m.Build();
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kArm64CompareAndBranch, s[0]->arch_opcode());
+ EXPECT_EQ(kEqual, s[0]->flags_condition());
+ EXPECT_EQ(3U, s[0]->InputCount());
+ EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+ }
+
+ {
+ StreamBuilder m(this, MachineType::Int64(), MachineType::Int64());
+ RawMachineLabel a, b;
+ Node* p0 = m.Parameter(0);
+ m.Branch(m.Word64NotEqual(p0, m.Int64Constant(0)), &a, &b);
+ m.Bind(&a);
+ m.Return(m.Int64Constant(1));
+ m.Bind(&b);
+ m.Return(m.Int64Constant(0));
+ Stream s = m.Build();
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kArm64CompareAndBranch, s[0]->arch_opcode());
+ EXPECT_EQ(kNotEqual, s[0]->flags_condition());
+ EXPECT_EQ(3U, s[0]->InputCount());
+ EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+ }
+}
// -----------------------------------------------------------------------------
// Add and subtract instructions with overflow.
@@ -1453,6 +1609,29 @@
}
}
+TEST_P(InstructionSelectorOvfAddSubTest, RORShift) {
+ // ADD and SUB do not support ROR shifts, make sure we do not try
+ // to merge them into the ADD/SUB instruction.
+ const MachInst2 dpi = GetParam();
+ const MachineType type = dpi.machine_type;
+ auto rotate = &RawMachineAssembler::Word64Ror;
+ ArchOpcode rotate_opcode = kArm64Ror;
+ if (type == MachineType::Int32()) {
+ rotate = &RawMachineAssembler::Word32Ror;
+ rotate_opcode = kArm64Ror32;
+ }
+ TRACED_FORRANGE(int32_t, imm, -32, 63) {
+ StreamBuilder m(this, type, type, type);
+ Node* const p0 = m.Parameter(0);
+ Node* const p1 = m.Parameter(1);
+ Node* r = (m.*rotate)(p1, m.Int32Constant(imm));
+ m.Return((m.*dpi.constructor)(p0, r));
+ Stream s = m.Build();
+ ASSERT_EQ(2U, s.size());
+ EXPECT_EQ(rotate_opcode, s[0]->arch_opcode());
+ EXPECT_EQ(dpi.arch_opcode, s[1]->arch_opcode());
+ }
+}
INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
InstructionSelectorOvfAddSubTest,
@@ -2846,6 +3025,7 @@
struct IntegerCmp {
MachInst2 mi;
FlagsCondition cond;
+ FlagsCondition commuted_cond;
};
@@ -2858,19 +3038,24 @@
const IntegerCmp kIntegerCmpInstructions[] = {
{{&RawMachineAssembler::Word32Equal, "Word32Equal", kArm64Cmp32,
MachineType::Int32()},
+ kEqual,
kEqual},
{{&RawMachineAssembler::Int32LessThan, "Int32LessThan", kArm64Cmp32,
MachineType::Int32()},
- kSignedLessThan},
+ kSignedLessThan,
+ kSignedGreaterThan},
{{&RawMachineAssembler::Int32LessThanOrEqual, "Int32LessThanOrEqual",
kArm64Cmp32, MachineType::Int32()},
- kSignedLessThanOrEqual},
+ kSignedLessThanOrEqual,
+ kSignedGreaterThanOrEqual},
{{&RawMachineAssembler::Uint32LessThan, "Uint32LessThan", kArm64Cmp32,
MachineType::Uint32()},
- kUnsignedLessThan},
+ kUnsignedLessThan,
+ kUnsignedGreaterThan},
{{&RawMachineAssembler::Uint32LessThanOrEqual, "Uint32LessThanOrEqual",
kArm64Cmp32, MachineType::Uint32()},
- kUnsignedLessThanOrEqual}};
+ kUnsignedLessThanOrEqual,
+ kUnsignedGreaterThanOrEqual}};
} // namespace
@@ -2907,6 +3092,156 @@
}
}
+TEST_F(InstructionSelectorTest, CmpWithImmediateOnLeft) {
+ TRACED_FOREACH(IntegerCmp, cmp, kIntegerCmpInstructions) {
+ TRACED_FOREACH(int32_t, imm, kAddSubImmediates) {
+ // kEqual and kNotEqual trigger the cbz/cbnz optimization, which
+ // is tested elsewhere.
+ if (cmp.cond == kEqual || cmp.cond == kNotEqual) continue;
+ StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
+ Node* const p0 = m.Parameter(0);
+ RawMachineLabel a, b;
+ m.Branch((m.*cmp.mi.constructor)(m.Int32Constant(imm), p0), &a, &b);
+ m.Bind(&a);
+ m.Return(m.Int32Constant(1));
+ m.Bind(&b);
+ m.Return(m.Int32Constant(0));
+ Stream s = m.Build();
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kArm64Cmp32, s[0]->arch_opcode());
+ ASSERT_LE(2U, s[0]->InputCount());
+ EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
+ EXPECT_EQ(cmp.commuted_cond, s[0]->flags_condition());
+ EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
+ }
+ }
+}
+
+TEST_F(InstructionSelectorTest, CmnWithImmediateOnLeft) {
+ TRACED_FOREACH(IntegerCmp, cmp, kIntegerCmpInstructions) {
+ TRACED_FOREACH(int32_t, imm, kAddSubImmediates) {
+ // kEqual and kNotEqual trigger the cbz/cbnz optimization, which
+ // is tested elsewhere.
+ if (cmp.cond == kEqual || cmp.cond == kNotEqual) continue;
+ StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
+ Node* sub = m.Int32Sub(m.Int32Constant(0), m.Parameter(0));
+ RawMachineLabel a, b;
+ m.Branch((m.*cmp.mi.constructor)(m.Int32Constant(imm), sub), &a, &b);
+ m.Bind(&a);
+ m.Return(m.Int32Constant(1));
+ m.Bind(&b);
+ m.Return(m.Int32Constant(0));
+ Stream s = m.Build();
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kArm64Cmn32, s[0]->arch_opcode());
+ ASSERT_LE(2U, s[0]->InputCount());
+ EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
+ EXPECT_EQ(cmp.cond, s[0]->flags_condition());
+ EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
+ }
+ }
+}
+
+TEST_F(InstructionSelectorTest, CmpSignedExtendByteOnLeft) {
+ TRACED_FOREACH(IntegerCmp, cmp, kIntegerCmpInstructions) {
+ StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
+ MachineType::Int32());
+ Node* extend = m.Word32Sar(m.Word32Shl(m.Parameter(0), m.Int32Constant(24)),
+ m.Int32Constant(24));
+ m.Return((m.*cmp.mi.constructor)(extend, m.Parameter(1)));
+ Stream s = m.Build();
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kArm64Cmp32, s[0]->arch_opcode());
+ EXPECT_EQ(kFlags_set, s[0]->flags_mode());
+ EXPECT_EQ(cmp.commuted_cond, s[0]->flags_condition());
+ EXPECT_EQ(kMode_Operand2_R_SXTB, s[0]->addressing_mode());
+ }
+}
+
+TEST_F(InstructionSelectorTest, CmnSignedExtendByteOnLeft) {
+ TRACED_FOREACH(IntegerCmp, cmp, kIntegerCmpInstructions) {
+ StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
+ MachineType::Int32());
+ Node* sub = m.Int32Sub(m.Int32Constant(0), m.Parameter(0));
+ Node* extend = m.Word32Sar(m.Word32Shl(m.Parameter(0), m.Int32Constant(24)),
+ m.Int32Constant(24));
+ m.Return((m.*cmp.mi.constructor)(extend, sub));
+ Stream s = m.Build();
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kArm64Cmn32, s[0]->arch_opcode());
+ EXPECT_EQ(kFlags_set, s[0]->flags_mode());
+ EXPECT_EQ(cmp.cond, s[0]->flags_condition());
+ EXPECT_EQ(kMode_Operand2_R_SXTB, s[0]->addressing_mode());
+ }
+}
+
+TEST_F(InstructionSelectorTest, CmpShiftByImmediateOnLeft) {
+ TRACED_FOREACH(IntegerCmp, cmp, kIntegerCmpInstructions) {
+ TRACED_FOREACH(Shift, shift, kShiftInstructions) {
+ // Only test relevant shifted operands.
+ if (shift.mi.machine_type != MachineType::Int32()) continue;
+
+ // The available shift operand range is `0 <= imm < 32`, but we also test
+ // that immediates outside this range are handled properly (modulo-32).
+ TRACED_FORRANGE(int, imm, -32, 63) {
+ StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
+ MachineType::Int32());
+ m.Return((m.*cmp.mi.constructor)(
+ (m.*shift.mi.constructor)(m.Parameter(1), m.Int32Constant(imm)),
+ m.Parameter(0)));
+ Stream s = m.Build();
+ // Cmp does not support ROR shifts.
+ if (shift.mi.arch_opcode == kArm64Ror32) {
+ ASSERT_EQ(2U, s.size());
+ continue;
+ }
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kArm64Cmp32, s[0]->arch_opcode());
+ EXPECT_EQ(shift.mode, s[0]->addressing_mode());
+ EXPECT_EQ(3U, s[0]->InputCount());
+ EXPECT_EQ(imm, s.ToInt64(s[0]->InputAt(2)));
+ EXPECT_EQ(1U, s[0]->OutputCount());
+ EXPECT_EQ(kFlags_set, s[0]->flags_mode());
+ EXPECT_EQ(cmp.commuted_cond, s[0]->flags_condition());
+ }
+ }
+ }
+}
+
+TEST_F(InstructionSelectorTest, CmnShiftByImmediateOnLeft) {
+ TRACED_FOREACH(IntegerCmp, cmp, kIntegerCmpInstructions) {
+ TRACED_FOREACH(Shift, shift, kShiftInstructions) {
+ // Only test relevant shifted operands.
+ if (shift.mi.machine_type != MachineType::Int32()) continue;
+
+ // The available shift operand range is `0 <= imm < 32`, but we also test
+ // that immediates outside this range are handled properly (modulo-32).
+ TRACED_FORRANGE(int, imm, -32, 63) {
+ StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
+ MachineType::Int32());
+ Node* sub = m.Int32Sub(m.Int32Constant(0), m.Parameter(0));
+ m.Return((m.*cmp.mi.constructor)(
+ (m.*shift.mi.constructor)(m.Parameter(1), m.Int32Constant(imm)),
+ sub));
+ Stream s = m.Build();
+ // Cmn does not support ROR shifts.
+ if (shift.mi.arch_opcode == kArm64Ror32) {
+ ASSERT_EQ(2U, s.size());
+ continue;
+ }
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kArm64Cmn32, s[0]->arch_opcode());
+ EXPECT_EQ(shift.mode, s[0]->addressing_mode());
+ EXPECT_EQ(3U, s[0]->InputCount());
+ EXPECT_EQ(imm, s.ToInt64(s[0]->InputAt(2)));
+ EXPECT_EQ(1U, s[0]->OutputCount());
+ EXPECT_EQ(kFlags_set, s[0]->flags_mode());
+ EXPECT_EQ(cmp.cond, s[0]->flags_condition());
+ }
+ }
+ }
+}
+
// -----------------------------------------------------------------------------
// Miscellaneous
@@ -3574,6 +3909,36 @@
EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
}
+TEST_F(InstructionSelectorTest, Float32Neg) {
+ StreamBuilder m(this, MachineType::Float32(), MachineType::Float32());
+ Node* const p0 = m.Parameter(0);
+ // Don't use m.Float32Neg() as that generates an explicit sub.
+ Node* const n = m.AddNode(m.machine()->Float32Neg().op(), m.Parameter(0));
+ m.Return(n);
+ Stream s = m.Build();
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kArm64Float32Neg, s[0]->arch_opcode());
+ ASSERT_EQ(1U, s[0]->InputCount());
+ EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+ ASSERT_EQ(1U, s[0]->OutputCount());
+ EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
+}
+
+TEST_F(InstructionSelectorTest, Float64Neg) {
+ StreamBuilder m(this, MachineType::Float64(), MachineType::Float64());
+ Node* const p0 = m.Parameter(0);
+ // Don't use m.Float64Neg() as that generates an explicit sub.
+ Node* const n = m.AddNode(m.machine()->Float64Neg().op(), m.Parameter(0));
+ m.Return(n);
+ Stream s = m.Build();
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kArm64Float64Neg, s[0]->arch_opcode());
+ ASSERT_EQ(1U, s[0]->InputCount());
+ EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+ ASSERT_EQ(1U, s[0]->OutputCount());
+ EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
+}
+
} // namespace compiler
} // namespace internal
} // namespace v8
diff --git a/test/unittests/compiler/checkpoint-elimination-unittest.cc b/test/unittests/compiler/checkpoint-elimination-unittest.cc
new file mode 100644
index 0000000..a201fc9
--- /dev/null
+++ b/test/unittests/compiler/checkpoint-elimination-unittest.cc
@@ -0,0 +1,59 @@
+// 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/checkpoint-elimination.h"
+#include "src/compiler/common-operator.h"
+#include "src/compiler/operator.h"
+#include "test/unittests/compiler/graph-reducer-unittest.h"
+#include "test/unittests/compiler/graph-unittest.h"
+#include "test/unittests/compiler/node-test-utils.h"
+
+using testing::StrictMock;
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+class CheckpointEliminationTest : public GraphTest {
+ public:
+ CheckpointEliminationTest() : GraphTest() {}
+ ~CheckpointEliminationTest() override {}
+
+ protected:
+ Reduction Reduce(AdvancedReducer::Editor* editor, Node* node) {
+ CheckpointElimination reducer(editor);
+ return reducer.Reduce(node);
+ }
+
+ Reduction Reduce(Node* node) {
+ StrictMock<MockAdvancedReducerEditor> editor;
+ return Reduce(&editor, node);
+ }
+};
+
+namespace {
+
+const Operator kOpNoWrite(0, Operator::kNoWrite, "OpNoWrite", 0, 1, 0, 0, 1, 0);
+
+} // namespace
+
+// -----------------------------------------------------------------------------
+// Checkpoint
+
+TEST_F(CheckpointEliminationTest, CheckpointChain) {
+ Node* const control = graph()->start();
+ Node* frame_state = EmptyFrameState();
+ Node* checkpoint1 = graph()->NewNode(common()->Checkpoint(), frame_state,
+ graph()->start(), control);
+ Node* effect_link = graph()->NewNode(&kOpNoWrite, checkpoint1);
+ Node* checkpoint2 = graph()->NewNode(common()->Checkpoint(), frame_state,
+ effect_link, control);
+ Reduction r = Reduce(checkpoint2);
+ ASSERT_TRUE(r.Changed());
+ EXPECT_EQ(effect_link, r.replacement());
+}
+
+} // namespace compiler
+} // namespace internal
+} // namespace v8
diff --git a/test/unittests/compiler/coalesced-live-ranges-unittest.cc b/test/unittests/compiler/coalesced-live-ranges-unittest.cc
deleted file mode 100644
index fe8fac4..0000000
--- a/test/unittests/compiler/coalesced-live-ranges-unittest.cc
+++ /dev/null
@@ -1,268 +0,0 @@
-// Copyright 2014 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/coalesced-live-ranges.h"
-#include "test/unittests/compiler/live-range-builder.h"
-#include "test/unittests/test-utils.h"
-
-namespace v8 {
-namespace internal {
-namespace compiler {
-
-
-class CoalescedLiveRangesTest : public TestWithZone {
- public:
- CoalescedLiveRangesTest() : TestWithZone(), ranges_(zone()) {}
- bool HasNoConflicts(const LiveRange* range);
- bool ConflictsPreciselyWith(const LiveRange* range, int id);
- bool ConflictsPreciselyWith(const LiveRange* range, int id1, int id2);
-
- CoalescedLiveRanges& ranges() { return ranges_; }
- const CoalescedLiveRanges& ranges() const { return ranges_; }
- bool AllocationsAreValid() const;
- void RemoveConflicts(LiveRange* range);
-
- private:
- typedef ZoneSet<int> LiveRangeIDs;
- bool IsRangeConflictingWith(const LiveRange* range, const LiveRangeIDs& ids);
- CoalescedLiveRanges ranges_;
-};
-
-
-bool CoalescedLiveRangesTest::ConflictsPreciselyWith(const LiveRange* range,
- int id) {
- LiveRangeIDs set(zone());
- set.insert(id);
- return IsRangeConflictingWith(range, set);
-}
-
-
-bool CoalescedLiveRangesTest::ConflictsPreciselyWith(const LiveRange* range,
- int id1, int id2) {
- LiveRangeIDs set(zone());
- set.insert(id1);
- set.insert(id2);
- return IsRangeConflictingWith(range, set);
-}
-
-
-bool CoalescedLiveRangesTest::HasNoConflicts(const LiveRange* range) {
- LiveRangeIDs set(zone());
- return IsRangeConflictingWith(range, set);
-}
-
-
-void CoalescedLiveRangesTest::RemoveConflicts(LiveRange* range) {
- auto conflicts = ranges().GetConflicts(range);
- LiveRangeIDs seen(zone());
- for (auto c = conflicts.Current(); c != nullptr;
- c = conflicts.RemoveCurrentAndGetNext()) {
- int id = c->TopLevel()->vreg();
- EXPECT_FALSE(seen.count(id) > 0);
- seen.insert(c->TopLevel()->vreg());
- }
-}
-
-
-bool CoalescedLiveRangesTest::AllocationsAreValid() const {
- return ranges().VerifyAllocationsAreValidForTesting();
-}
-
-
-bool CoalescedLiveRangesTest::IsRangeConflictingWith(const LiveRange* range,
- const LiveRangeIDs& ids) {
- LiveRangeIDs found_ids(zone());
-
- auto conflicts = ranges().GetConflicts(range);
- for (auto conflict = conflicts.Current(); conflict != nullptr;
- conflict = conflicts.GetNext()) {
- found_ids.insert(conflict->TopLevel()->vreg());
- }
- return found_ids == ids;
-}
-
-
-TEST_F(CoalescedLiveRangesTest, VisitEmptyAllocations) {
- LiveRange* range = TestRangeBuilder(zone()).Id(1).Build(1, 5);
- ASSERT_TRUE(ranges().empty());
- ASSERT_TRUE(AllocationsAreValid());
- ASSERT_TRUE(HasNoConflicts(range));
-}
-
-
-TEST_F(CoalescedLiveRangesTest, CandidateBeforeAfterAllocations) {
- LiveRange* range = TestRangeBuilder(zone()).Id(1).Build(5, 6);
- ranges().AllocateRange(range);
- ASSERT_FALSE(ranges().empty());
- ASSERT_TRUE(AllocationsAreValid());
- LiveRange* query = TestRangeBuilder(zone()).Id(2).Build(1, 2);
- ASSERT_TRUE(HasNoConflicts(query));
- query = TestRangeBuilder(zone()).Id(3).Build(1, 5);
- ASSERT_TRUE(HasNoConflicts(query));
-}
-
-
-TEST_F(CoalescedLiveRangesTest, CandidateBeforeAfterManyAllocations) {
- LiveRange* range =
- TestRangeBuilder(zone()).Id(1).Add(5, 7).Add(10, 12).Build();
- ranges().AllocateRange(range);
- ASSERT_FALSE(ranges().empty());
- ASSERT_TRUE(AllocationsAreValid());
- LiveRange* query =
- TestRangeBuilder(zone()).Id(2).Add(1, 2).Add(13, 15).Build();
- ASSERT_TRUE(HasNoConflicts(query));
- query = TestRangeBuilder(zone()).Id(3).Add(1, 5).Add(12, 15).Build();
- ASSERT_TRUE(HasNoConflicts(query));
-}
-
-
-TEST_F(CoalescedLiveRangesTest, SelfConflictsPreciselyWithSelf) {
- LiveRange* range = TestRangeBuilder(zone()).Id(1).Build(1, 5);
- ranges().AllocateRange(range);
- ASSERT_FALSE(ranges().empty());
- ASSERT_TRUE(AllocationsAreValid());
- ASSERT_TRUE(ConflictsPreciselyWith(range, 1));
- range = TestRangeBuilder(zone()).Id(2).Build(8, 10);
- ranges().AllocateRange(range);
- ASSERT_TRUE(ConflictsPreciselyWith(range, 2));
-}
-
-
-TEST_F(CoalescedLiveRangesTest, QueryStartsBeforeConflict) {
- LiveRange* range = TestRangeBuilder(zone()).Id(1).Build(2, 5);
- ranges().AllocateRange(range);
- LiveRange* query = TestRangeBuilder(zone()).Id(2).Build(1, 3);
- ASSERT_TRUE(ConflictsPreciselyWith(query, 1));
- range = TestRangeBuilder(zone()).Id(3).Build(8, 10);
- ranges().AllocateRange(range);
- query = TestRangeBuilder(zone()).Id(4).Build(6, 9);
- ASSERT_TRUE(ConflictsPreciselyWith(query, 3));
-}
-
-
-TEST_F(CoalescedLiveRangesTest, QueryStartsInConflict) {
- LiveRange* range = TestRangeBuilder(zone()).Id(1).Build(2, 5);
- ranges().AllocateRange(range);
- LiveRange* query = TestRangeBuilder(zone()).Id(2).Build(3, 6);
- ASSERT_TRUE(ConflictsPreciselyWith(query, 1));
- range = TestRangeBuilder(zone()).Id(3).Build(8, 10);
- ranges().AllocateRange(range);
- query = TestRangeBuilder(zone()).Id(4).Build(9, 11);
- ASSERT_TRUE(ConflictsPreciselyWith(query, 3));
-}
-
-
-TEST_F(CoalescedLiveRangesTest, QueryContainedInConflict) {
- LiveRange* range = TestRangeBuilder(zone()).Id(1).Build(1, 5);
- ranges().AllocateRange(range);
- LiveRange* query = TestRangeBuilder(zone()).Id(2).Build(2, 3);
- ASSERT_TRUE(ConflictsPreciselyWith(query, 1));
-}
-
-
-TEST_F(CoalescedLiveRangesTest, QueryContainsConflict) {
- LiveRange* range = TestRangeBuilder(zone()).Id(1).Build(2, 3);
- ranges().AllocateRange(range);
- LiveRange* query = TestRangeBuilder(zone()).Id(2).Build(1, 5);
- ASSERT_TRUE(ConflictsPreciselyWith(query, 1));
-}
-
-
-TEST_F(CoalescedLiveRangesTest, QueryCoversManyIntervalsSameRange) {
- LiveRange* range =
- TestRangeBuilder(zone()).Id(1).Add(1, 5).Add(7, 9).Add(20, 25).Build();
- ranges().AllocateRange(range);
- LiveRange* query = TestRangeBuilder(zone()).Id(2).Build(2, 8);
- ASSERT_TRUE(ConflictsPreciselyWith(query, 1));
-}
-
-
-TEST_F(CoalescedLiveRangesTest, QueryCoversManyIntervalsDifferentRanges) {
- LiveRange* range =
- TestRangeBuilder(zone()).Id(1).Add(1, 5).Add(20, 25).Build();
- ranges().AllocateRange(range);
- range = TestRangeBuilder(zone()).Id(2).Build(7, 10);
- ranges().AllocateRange(range);
- LiveRange* query = TestRangeBuilder(zone()).Id(3).Build(2, 22);
- ASSERT_TRUE(ConflictsPreciselyWith(query, 1, 2));
-}
-
-
-TEST_F(CoalescedLiveRangesTest, QueryFitsInGaps) {
- LiveRange* range =
- TestRangeBuilder(zone()).Id(1).Add(1, 5).Add(10, 15).Add(20, 25).Build();
- ranges().AllocateRange(range);
- LiveRange* query =
- TestRangeBuilder(zone()).Id(3).Add(5, 10).Add(16, 19).Add(27, 30).Build();
- ASSERT_TRUE(HasNoConflicts(query));
-}
-
-
-TEST_F(CoalescedLiveRangesTest, DeleteConflictBefore) {
- LiveRange* range = TestRangeBuilder(zone()).Id(1).Add(1, 4).Add(5, 6).Build();
- ranges().AllocateRange(range);
- range = TestRangeBuilder(zone()).Id(2).Build(40, 50);
- ranges().AllocateRange(range);
- LiveRange* query = TestRangeBuilder(zone()).Id(3).Build(3, 7);
- RemoveConflicts(query);
- query = TestRangeBuilder(zone()).Id(4).Build(0, 60);
- ASSERT_TRUE(ConflictsPreciselyWith(query, 2));
-}
-
-
-TEST_F(CoalescedLiveRangesTest, DeleteConflictAfter) {
- LiveRange* range = TestRangeBuilder(zone()).Id(1).Build(1, 5);
- ranges().AllocateRange(range);
- range = TestRangeBuilder(zone()).Id(2).Add(40, 50).Add(60, 70).Build();
- ranges().AllocateRange(range);
- LiveRange* query = TestRangeBuilder(zone()).Id(3).Build(45, 60);
- RemoveConflicts(query);
- query = TestRangeBuilder(zone()).Id(4).Build(0, 60);
- ASSERT_TRUE(ConflictsPreciselyWith(query, 1));
-}
-
-
-TEST_F(CoalescedLiveRangesTest, DeleteConflictStraddle) {
- LiveRange* range =
- TestRangeBuilder(zone()).Id(1).Add(1, 5).Add(10, 20).Build();
- ranges().AllocateRange(range);
- range = TestRangeBuilder(zone()).Id(2).Build(40, 50);
- ranges().AllocateRange(range);
- LiveRange* query = TestRangeBuilder(zone()).Id(3).Build(4, 15);
- RemoveConflicts(query);
- query = TestRangeBuilder(zone()).Id(4).Build(0, 60);
- ASSERT_TRUE(ConflictsPreciselyWith(query, 2));
-}
-
-
-TEST_F(CoalescedLiveRangesTest, DeleteConflictManyOverlapsBefore) {
- LiveRange* range =
- TestRangeBuilder(zone()).Id(1).Add(1, 5).Add(6, 10).Add(10, 20).Build();
- ranges().AllocateRange(range);
- range = TestRangeBuilder(zone()).Id(2).Build(40, 50);
- ranges().AllocateRange(range);
- LiveRange* query = TestRangeBuilder(zone()).Id(3).Build(4, 15);
- RemoveConflicts(query);
- query = TestRangeBuilder(zone()).Id(4).Build(0, 60);
- ASSERT_TRUE(ConflictsPreciselyWith(query, 2));
-}
-
-
-TEST_F(CoalescedLiveRangesTest, DeleteWhenConflictRepeatsAfterNonConflict) {
- LiveRange* range =
- TestRangeBuilder(zone()).Id(1).Add(1, 5).Add(6, 10).Add(20, 30).Build();
- ranges().AllocateRange(range);
- range = TestRangeBuilder(zone()).Id(2).Build(12, 15);
- ranges().AllocateRange(range);
- LiveRange* query =
- TestRangeBuilder(zone()).Id(3).Add(1, 8).Add(22, 25).Build();
- RemoveConflicts(query);
- query = TestRangeBuilder(zone()).Id(4).Build(0, 60);
- ASSERT_TRUE(ConflictsPreciselyWith(query, 2));
-}
-
-
-} // namespace compiler
-} // namespace internal
-} // namespace v8
diff --git a/test/unittests/compiler/common-operator-unittest.cc b/test/unittests/compiler/common-operator-unittest.cc
index 0a55a2e..52f99a5 100644
--- a/test/unittests/compiler/common-operator-unittest.cc
+++ b/test/unittests/compiler/common-operator-unittest.cc
@@ -362,15 +362,26 @@
TEST_F(CommonOperatorTest, BeginRegion) {
- const Operator* op = common()->BeginRegion();
- EXPECT_EQ(1, op->EffectInputCount());
- EXPECT_EQ(1, OperatorProperties::GetTotalInputCount(op));
- EXPECT_EQ(0, op->ControlOutputCount());
- EXPECT_EQ(1, op->EffectOutputCount());
- EXPECT_EQ(0, op->ValueOutputCount());
+ {
+ const Operator* op =
+ common()->BeginRegion(RegionObservability::kObservable);
+ EXPECT_EQ(1, op->EffectInputCount());
+ EXPECT_EQ(1, OperatorProperties::GetTotalInputCount(op));
+ EXPECT_EQ(0, op->ControlOutputCount());
+ EXPECT_EQ(1, op->EffectOutputCount());
+ EXPECT_EQ(0, op->ValueOutputCount());
+ }
+ {
+ const Operator* op =
+ common()->BeginRegion(RegionObservability::kNotObservable);
+ EXPECT_EQ(1, op->EffectInputCount());
+ EXPECT_EQ(1, OperatorProperties::GetTotalInputCount(op));
+ EXPECT_EQ(0, op->ControlOutputCount());
+ EXPECT_EQ(1, op->EffectOutputCount());
+ EXPECT_EQ(0, op->ValueOutputCount());
+ }
}
-
TEST_F(CommonOperatorTest, FinishRegion) {
const Operator* op = common()->FinishRegion();
EXPECT_EQ(1, op->ValueInputCount());
@@ -381,6 +392,19 @@
EXPECT_EQ(1, op->ValueOutputCount());
}
+TEST_F(CommonOperatorTest, Projection) {
+ TRACED_FORRANGE(size_t, index, 0, 3) {
+ const Operator* op = common()->Projection(index);
+ EXPECT_EQ(index, ProjectionIndexOf(op));
+ EXPECT_EQ(1, op->ValueInputCount());
+ EXPECT_EQ(1, op->ControlInputCount());
+ EXPECT_EQ(2, OperatorProperties::GetTotalInputCount(op));
+ EXPECT_EQ(0, op->ControlOutputCount());
+ EXPECT_EQ(0, op->EffectOutputCount());
+ EXPECT_EQ(1, op->ValueOutputCount());
+ }
+}
+
} // namespace compiler
} // namespace internal
} // namespace v8
diff --git a/test/unittests/compiler/escape-analysis-unittest.cc b/test/unittests/compiler/escape-analysis-unittest.cc
index 4c17ef2..9b584a2 100644
--- a/test/unittests/compiler/escape-analysis-unittest.cc
+++ b/test/unittests/compiler/escape-analysis-unittest.cc
@@ -48,7 +48,8 @@
effect = effect_;
}
- return effect_ = graph()->NewNode(common()->BeginRegion(), effect);
+ return effect_ = graph()->NewNode(
+ common()->BeginRegion(RegionObservability::kObservable), effect);
}
Node* FinishRegion(Node* value, Node* effect = nullptr) {
diff --git a/test/unittests/compiler/graph-unittest.h b/test/unittests/compiler/graph-unittest.h
index 31bae6d..d4248e4 100644
--- a/test/unittests/compiler/graph-unittest.h
+++ b/test/unittests/compiler/graph-unittest.h
@@ -48,6 +48,9 @@
Node* EmptyFrameState();
+ Matcher<Node*> IsBooleanConstant(bool value) {
+ return value ? IsTrueConstant() : IsFalseConstant();
+ }
Matcher<Node*> IsFalseConstant();
Matcher<Node*> IsTrueConstant();
Matcher<Node*> IsUndefinedConstant();
diff --git a/test/unittests/compiler/instruction-selector-unittest.cc b/test/unittests/compiler/instruction-selector-unittest.cc
index 69ae768..936a94e 100644
--- a/test/unittests/compiler/instruction-selector-unittest.cc
+++ b/test/unittests/compiler/instruction-selector-unittest.cc
@@ -45,9 +45,8 @@
selector.SelectInstructions();
if (FLAG_trace_turbo) {
OFStream out(stdout);
- PrintableInstructionSequence printable = {
- RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN),
- &sequence};
+ PrintableInstructionSequence printable = {RegisterConfiguration::Turbofan(),
+ &sequence};
out << "=== Code sequence after instruction selection ===" << std::endl
<< printable;
}
@@ -94,12 +93,12 @@
}
for (auto i : s.virtual_registers_) {
int const virtual_register = i.second;
- if (sequence.IsFloat(virtual_register)) {
+ if (sequence.IsFP(virtual_register)) {
EXPECT_FALSE(sequence.IsReference(virtual_register));
s.doubles_.insert(virtual_register);
}
if (sequence.IsReference(virtual_register)) {
- EXPECT_FALSE(sequence.IsFloat(virtual_register));
+ EXPECT_FALSE(sequence.IsFP(virtual_register));
s.references_.insert(virtual_register);
}
}
@@ -333,7 +332,8 @@
Node* p2 = m2.Parameter(0);
m2.Return(m2.AddNode(
m2.machine()->Load(MachineType::Int32()), p2, m2.Int32Constant(0),
- m2.AddNode(m2.common()->BeginRegion(), m2.graph()->start())));
+ m2.AddNode(m2.common()->BeginRegion(RegionObservability::kObservable),
+ m2.graph()->start())));
Stream s2 = m2.Build(kAllInstructions);
EXPECT_LE(3U, s1.size());
ASSERT_EQ(s1.size(), s2.size());
@@ -480,7 +480,7 @@
EXPECT_EQ(0, s.ToInt32(call_instr->InputAt(4))); // This should be a context.
// We inserted 0 here.
EXPECT_EQ(0.5, s.ToFloat64(call_instr->InputAt(5)));
- EXPECT_TRUE(s.ToHeapObject(call_instr->InputAt(6))->IsUndefined());
+ EXPECT_TRUE(s.ToHeapObject(call_instr->InputAt(6))->IsUndefined(isolate()));
EXPECT_EQ(MachineType::AnyTagged(),
desc_before->GetType(0)); // function is always
// tagged/any.
diff --git a/test/unittests/compiler/instruction-sequence-unittest.cc b/test/unittests/compiler/instruction-sequence-unittest.cc
index 9360ca4..619e0aa 100644
--- a/test/unittests/compiler/instruction-sequence-unittest.cc
+++ b/test/unittests/compiler/instruction-sequence-unittest.cc
@@ -67,8 +67,11 @@
if (config_.is_empty()) {
config_.Reset(new RegisterConfiguration(
num_general_registers_, num_double_registers_, num_general_registers_,
- num_double_registers_, num_double_registers_, allocatable_codes,
- allocatable_double_codes, general_register_names_,
+ num_double_registers_, allocatable_codes, allocatable_double_codes,
+ kSimpleFPAliasing ? RegisterConfiguration::OVERLAP
+ : RegisterConfiguration::COMBINE,
+ general_register_names_,
+ double_register_names_, // float register names
double_register_names_));
}
return config_.get();
diff --git a/test/unittests/compiler/int64-lowering-unittest.cc b/test/unittests/compiler/int64-lowering-unittest.cc
index 8bc02c5..804c399 100644
--- a/test/unittests/compiler/int64-lowering-unittest.cc
+++ b/test/unittests/compiler/int64-lowering-unittest.cc
@@ -133,6 +133,7 @@
MachineRepresentation::kWord64);
Capture<Node*> high_word_load;
+#if defined(V8_TARGET_LITTLE_ENDIAN)
Matcher<Node*> high_word_load_matcher =
IsLoad(MachineType::Int32(), IsInt32Constant(base),
IsInt32Add(IsInt32Constant(index), IsInt32Constant(0x4)), start(),
@@ -146,6 +147,21 @@
start()),
AllOf(CaptureEq(&high_word_load), high_word_load_matcher),
start(), start()));
+#elif defined(V8_TARGET_BIG_ENDIAN)
+ Matcher<Node*> high_word_load_matcher =
+ IsLoad(MachineType::Int32(), IsInt32Constant(base),
+ IsInt32Constant(index), start(), start());
+
+ EXPECT_THAT(
+ graph()->end()->InputAt(1),
+ IsReturn2(
+ IsLoad(MachineType::Int32(), IsInt32Constant(base),
+ IsInt32Add(IsInt32Constant(index), IsInt32Constant(0x4)),
+ AllOf(CaptureEq(&high_word_load), high_word_load_matcher),
+ start()),
+ AllOf(CaptureEq(&high_word_load), high_word_load_matcher), start(),
+ start()));
+#endif
}
TEST_F(Int64LoweringTest, Int64Store) {
@@ -177,6 +193,7 @@
const StoreRepresentation rep(MachineRepresentation::kWord32,
kNoWriteBarrier);
+#if defined(V8_TARGET_LITTLE_ENDIAN)
EXPECT_THAT(
graph()->end()->InputAt(1),
IsReturn(
@@ -189,6 +206,20 @@
IsInt32Constant(high_word_value(0)), start(), start()),
start()),
start()));
+#elif defined(V8_TARGET_BIG_ENDIAN)
+ EXPECT_THAT(
+ graph()->end()->InputAt(1),
+ IsReturn(
+ IsInt32Constant(return_value),
+ IsStore(
+ rep, IsInt32Constant(base),
+ IsInt32Add(IsInt32Constant(index), IsInt32Constant(4)),
+ IsInt32Constant(low_word_value(0)),
+ IsStore(rep, IsInt32Constant(base), IsInt32Constant(index),
+ IsInt32Constant(high_word_value(0)), start(), start()),
+ start()),
+ start()));
+#endif
}
TEST_F(Int64LoweringTest, Int64And) {
@@ -526,12 +557,13 @@
IsStore(StoreRepresentation(MachineRepresentation::kWord32,
WriteBarrierKind::kNoWriteBarrier),
AllOf(CaptureEq(&stack_slot_capture), stack_slot_matcher),
- IsInt32Constant(0), IsInt32Constant(low_word_value(0)),
+ IsInt32Constant(Int64Lowering::kLowerWordOffset),
+ IsInt32Constant(low_word_value(0)),
IsStore(StoreRepresentation(MachineRepresentation::kWord32,
WriteBarrierKind::kNoWriteBarrier),
AllOf(CaptureEq(&stack_slot_capture), stack_slot_matcher),
- IsInt32Constant(4), IsInt32Constant(high_word_value(0)),
- start(), start()),
+ IsInt32Constant(Int64Lowering::kHigherWordOffset),
+ IsInt32Constant(high_word_value(0)), start(), start()),
start());
EXPECT_THAT(
@@ -563,11 +595,11 @@
graph()->end()->InputAt(1),
IsReturn2(IsLoad(MachineType::Int32(),
AllOf(CaptureEq(&stack_slot), stack_slot_matcher),
- IsInt32Constant(0),
+ IsInt32Constant(Int64Lowering::kLowerWordOffset),
AllOf(CaptureEq(&store), store_matcher), start()),
IsLoad(MachineType::Int32(),
AllOf(CaptureEq(&stack_slot), stack_slot_matcher),
- IsInt32Constant(0x4),
+ IsInt32Constant(Int64Lowering::kHigherWordOffset),
AllOf(CaptureEq(&store), store_matcher), start()),
start(), start()));
}
diff --git a/test/unittests/compiler/js-builtin-reducer-unittest.cc b/test/unittests/compiler/js-builtin-reducer-unittest.cc
index 0f8eed7..9a1378a 100644
--- a/test/unittests/compiler/js-builtin-reducer-unittest.cc
+++ b/test/unittests/compiler/js-builtin-reducer-unittest.cc
@@ -49,6 +49,19 @@
return HeapConstant(f);
}
+ Node* StringFunction(const char* name) {
+ Handle<Object> m =
+ JSObject::GetProperty(
+ isolate()->global_object(),
+ isolate()->factory()->NewStringFromAsciiChecked("String"))
+ .ToHandleChecked();
+ Handle<JSFunction> f = Handle<JSFunction>::cast(
+ Object::GetProperty(
+ m, isolate()->factory()->NewStringFromAsciiChecked(name))
+ .ToHandleChecked());
+ return HeapConstant(f);
+ }
+
JSOperatorBuilder* javascript() { return &javascript_; }
private:
@@ -74,10 +87,519 @@
// -----------------------------------------------------------------------------
+// Math.abs
+
+TEST_F(JSBuiltinReducerTest, MathAbsWithNumber) {
+ Node* function = MathFunction("abs");
+
+ Node* effect = graph()->start();
+ Node* control = graph()->start();
+ Node* context = UndefinedConstant();
+ Node* frame_state = graph()->start();
+ TRACED_FOREACH(Type*, t0, kNumberTypes) {
+ Node* p0 = Parameter(t0, 0);
+ Node* call = graph()->NewNode(javascript()->CallFunction(3), function,
+ UndefinedConstant(), p0, context, frame_state,
+ effect, control);
+ Reduction r = Reduce(call);
+
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(), IsNumberAbs(p0));
+ }
+}
+
+TEST_F(JSBuiltinReducerTest, MathAbsWithPlainPrimitive) {
+ Node* function = MathFunction("abs");
+
+ Node* effect = graph()->start();
+ Node* control = graph()->start();
+ Node* context = UndefinedConstant();
+ Node* frame_state = graph()->start();
+ Node* p0 = Parameter(Type::PlainPrimitive(), 0);
+ Node* call = graph()->NewNode(javascript()->CallFunction(3), function,
+ UndefinedConstant(), p0, context, frame_state,
+ effect, control);
+ Reduction r = Reduce(call);
+
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(), IsNumberAbs(IsPlainPrimitiveToNumber(p0)));
+}
+
+// -----------------------------------------------------------------------------
+// Math.atan
+
+TEST_F(JSBuiltinReducerTest, MathAtanWithNumber) {
+ Node* function = MathFunction("atan");
+
+ Node* effect = graph()->start();
+ Node* control = graph()->start();
+ Node* context = UndefinedConstant();
+ Node* frame_state = graph()->start();
+ TRACED_FOREACH(Type*, t0, kNumberTypes) {
+ Node* p0 = Parameter(t0, 0);
+ Node* call = graph()->NewNode(javascript()->CallFunction(3), function,
+ UndefinedConstant(), p0, context, frame_state,
+ effect, control);
+ Reduction r = Reduce(call);
+
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(), IsNumberAtan(p0));
+ }
+}
+
+TEST_F(JSBuiltinReducerTest, MathAtanWithPlainPrimitive) {
+ Node* function = MathFunction("atan");
+
+ Node* effect = graph()->start();
+ Node* control = graph()->start();
+ Node* context = UndefinedConstant();
+ Node* frame_state = graph()->start();
+ Node* p0 = Parameter(Type::PlainPrimitive(), 0);
+ Node* call = graph()->NewNode(javascript()->CallFunction(3), function,
+ UndefinedConstant(), p0, context, frame_state,
+ effect, control);
+ Reduction r = Reduce(call);
+
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(), IsNumberAtan(IsPlainPrimitiveToNumber(p0)));
+}
+
+// -----------------------------------------------------------------------------
+// Math.atan2
+
+TEST_F(JSBuiltinReducerTest, MathAtan2WithNumber) {
+ Node* function = MathFunction("atan2");
+
+ Node* effect = graph()->start();
+ Node* control = graph()->start();
+ Node* context = UndefinedConstant();
+ Node* frame_state = graph()->start();
+ TRACED_FOREACH(Type*, t0, kNumberTypes) {
+ Node* p0 = Parameter(t0, 0);
+ TRACED_FOREACH(Type*, t1, kNumberTypes) {
+ Node* p1 = Parameter(t1, 0);
+ Node* call = graph()->NewNode(javascript()->CallFunction(4), function,
+ UndefinedConstant(), p0, p1, context,
+ frame_state, effect, control);
+ Reduction r = Reduce(call);
+
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(), IsNumberAtan2(p0, p1));
+ }
+ }
+}
+
+TEST_F(JSBuiltinReducerTest, MathAtan2WithPlainPrimitive) {
+ Node* function = MathFunction("atan2");
+
+ Node* effect = graph()->start();
+ Node* control = graph()->start();
+ Node* context = UndefinedConstant();
+ Node* frame_state = graph()->start();
+ Node* p0 = Parameter(Type::PlainPrimitive(), 0);
+ Node* p1 = Parameter(Type::PlainPrimitive(), 0);
+ Node* call = graph()->NewNode(javascript()->CallFunction(4), function,
+ UndefinedConstant(), p0, p1, context,
+ frame_state, effect, control);
+ Reduction r = Reduce(call);
+
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(), IsNumberAtan2(IsPlainPrimitiveToNumber(p0),
+ IsPlainPrimitiveToNumber(p1)));
+}
+
+// -----------------------------------------------------------------------------
+// Math.ceil
+
+TEST_F(JSBuiltinReducerTest, MathCeilWithNumber) {
+ Node* function = MathFunction("ceil");
+
+ Node* effect = graph()->start();
+ Node* control = graph()->start();
+ Node* context = UndefinedConstant();
+ Node* frame_state = graph()->start();
+ TRACED_FOREACH(Type*, t0, kNumberTypes) {
+ Node* p0 = Parameter(t0, 0);
+ Node* call = graph()->NewNode(javascript()->CallFunction(3), function,
+ UndefinedConstant(), p0, context, frame_state,
+ effect, control);
+ Reduction r = Reduce(call);
+
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(), IsNumberCeil(p0));
+ }
+}
+
+TEST_F(JSBuiltinReducerTest, MathCeilWithPlainPrimitive) {
+ Node* function = MathFunction("ceil");
+
+ Node* effect = graph()->start();
+ Node* control = graph()->start();
+ Node* context = UndefinedConstant();
+ Node* frame_state = graph()->start();
+ Node* p0 = Parameter(Type::PlainPrimitive(), 0);
+ Node* call = graph()->NewNode(javascript()->CallFunction(3), function,
+ UndefinedConstant(), p0, context, frame_state,
+ effect, control);
+ Reduction r = Reduce(call);
+
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(), IsNumberCeil(IsPlainPrimitiveToNumber(p0)));
+}
+
+// -----------------------------------------------------------------------------
+// Math.clz32
+
+TEST_F(JSBuiltinReducerTest, MathClz32WithUnsigned32) {
+ Node* function = MathFunction("clz32");
+
+ Node* effect = graph()->start();
+ Node* control = graph()->start();
+ Node* context = UndefinedConstant();
+ Node* frame_state = graph()->start();
+ Node* p0 = Parameter(Type::Unsigned32(), 0);
+ Node* call = graph()->NewNode(javascript()->CallFunction(3), function,
+ UndefinedConstant(), p0, context, frame_state,
+ effect, control);
+ Reduction r = Reduce(call);
+
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(), IsNumberClz32(p0));
+}
+
+TEST_F(JSBuiltinReducerTest, MathClz32WithNumber) {
+ Node* function = MathFunction("clz32");
+
+ Node* effect = graph()->start();
+ Node* control = graph()->start();
+ Node* context = UndefinedConstant();
+ Node* frame_state = graph()->start();
+ Node* p0 = Parameter(Type::Number(), 0);
+ Node* call = graph()->NewNode(javascript()->CallFunction(3), function,
+ UndefinedConstant(), p0, context, frame_state,
+ effect, control);
+ Reduction r = Reduce(call);
+
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(), IsNumberClz32(IsNumberToUint32(p0)));
+}
+
+TEST_F(JSBuiltinReducerTest, MathClz32WithPlainPrimitive) {
+ Node* function = MathFunction("clz32");
+
+ Node* effect = graph()->start();
+ Node* control = graph()->start();
+ Node* context = UndefinedConstant();
+ Node* frame_state = graph()->start();
+ Node* p0 = Parameter(Type::PlainPrimitive(), 0);
+ Node* call = graph()->NewNode(javascript()->CallFunction(3), function,
+ UndefinedConstant(), p0, context, frame_state,
+ effect, control);
+ Reduction r = Reduce(call);
+
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(),
+ IsNumberClz32(IsNumberToUint32(IsPlainPrimitiveToNumber(p0))));
+}
+
+// -----------------------------------------------------------------------------
+// Math.cos
+
+TEST_F(JSBuiltinReducerTest, MathCosWithNumber) {
+ Node* function = MathFunction("cos");
+
+ Node* effect = graph()->start();
+ Node* control = graph()->start();
+ Node* context = UndefinedConstant();
+ Node* frame_state = graph()->start();
+ TRACED_FOREACH(Type*, t0, kNumberTypes) {
+ Node* p0 = Parameter(t0, 0);
+ Node* call = graph()->NewNode(javascript()->CallFunction(3), function,
+ UndefinedConstant(), p0, context, frame_state,
+ effect, control);
+ Reduction r = Reduce(call);
+
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(), IsNumberCos(p0));
+ }
+}
+
+TEST_F(JSBuiltinReducerTest, MathCosWithPlainPrimitive) {
+ Node* function = MathFunction("cos");
+
+ Node* effect = graph()->start();
+ Node* control = graph()->start();
+ Node* context = UndefinedConstant();
+ Node* frame_state = graph()->start();
+ Node* p0 = Parameter(Type::PlainPrimitive(), 0);
+ Node* call = graph()->NewNode(javascript()->CallFunction(3), function,
+ UndefinedConstant(), p0, context, frame_state,
+ effect, control);
+ Reduction r = Reduce(call);
+
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(), IsNumberCos(IsPlainPrimitiveToNumber(p0)));
+}
+
+// -----------------------------------------------------------------------------
+// Math.exp
+
+TEST_F(JSBuiltinReducerTest, MathExpWithNumber) {
+ Node* function = MathFunction("exp");
+
+ Node* effect = graph()->start();
+ Node* control = graph()->start();
+ Node* context = UndefinedConstant();
+ Node* frame_state = graph()->start();
+ TRACED_FOREACH(Type*, t0, kNumberTypes) {
+ Node* p0 = Parameter(t0, 0);
+ Node* call = graph()->NewNode(javascript()->CallFunction(3), function,
+ UndefinedConstant(), p0, context, frame_state,
+ effect, control);
+ Reduction r = Reduce(call);
+
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(), IsNumberExp(p0));
+ }
+}
+
+TEST_F(JSBuiltinReducerTest, MathExpWithPlainPrimitive) {
+ Node* function = MathFunction("exp");
+
+ Node* effect = graph()->start();
+ Node* control = graph()->start();
+ Node* context = UndefinedConstant();
+ Node* frame_state = graph()->start();
+ Node* p0 = Parameter(Type::PlainPrimitive(), 0);
+ Node* call = graph()->NewNode(javascript()->CallFunction(3), function,
+ UndefinedConstant(), p0, context, frame_state,
+ effect, control);
+ Reduction r = Reduce(call);
+
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(), IsNumberExp(IsPlainPrimitiveToNumber(p0)));
+}
+
+// -----------------------------------------------------------------------------
+// Math.floor
+
+TEST_F(JSBuiltinReducerTest, MathFloorWithNumber) {
+ Node* function = MathFunction("floor");
+
+ Node* effect = graph()->start();
+ Node* control = graph()->start();
+ Node* context = UndefinedConstant();
+ Node* frame_state = graph()->start();
+ TRACED_FOREACH(Type*, t0, kNumberTypes) {
+ Node* p0 = Parameter(t0, 0);
+ Node* call = graph()->NewNode(javascript()->CallFunction(3), function,
+ UndefinedConstant(), p0, context, frame_state,
+ effect, control);
+ Reduction r = Reduce(call);
+
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(), IsNumberFloor(p0));
+ }
+}
+
+TEST_F(JSBuiltinReducerTest, MathFloorWithPlainPrimitive) {
+ Node* function = MathFunction("floor");
+
+ Node* effect = graph()->start();
+ Node* control = graph()->start();
+ Node* context = UndefinedConstant();
+ Node* frame_state = graph()->start();
+ Node* p0 = Parameter(Type::PlainPrimitive(), 0);
+ Node* call = graph()->NewNode(javascript()->CallFunction(3), function,
+ UndefinedConstant(), p0, context, frame_state,
+ effect, control);
+ Reduction r = Reduce(call);
+
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(), IsNumberFloor(IsPlainPrimitiveToNumber(p0)));
+}
+
+// -----------------------------------------------------------------------------
+// Math.fround
+
+TEST_F(JSBuiltinReducerTest, MathFroundWithNumber) {
+ Node* function = MathFunction("fround");
+
+ Node* effect = graph()->start();
+ Node* control = graph()->start();
+ Node* context = UndefinedConstant();
+ Node* frame_state = graph()->start();
+ TRACED_FOREACH(Type*, t0, kNumberTypes) {
+ Node* p0 = Parameter(t0, 0);
+ Node* call = graph()->NewNode(javascript()->CallFunction(3), function,
+ UndefinedConstant(), p0, context, frame_state,
+ effect, control);
+ Reduction r = Reduce(call);
+
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(), IsNumberFround(p0));
+ }
+}
+
+TEST_F(JSBuiltinReducerTest, MathFroundWithPlainPrimitive) {
+ Node* function = MathFunction("fround");
+
+ Node* effect = graph()->start();
+ Node* control = graph()->start();
+ Node* context = UndefinedConstant();
+ Node* frame_state = graph()->start();
+ Node* p0 = Parameter(Type::PlainPrimitive(), 0);
+ Node* call = graph()->NewNode(javascript()->CallFunction(3), function,
+ UndefinedConstant(), p0, context, frame_state,
+ effect, control);
+ Reduction r = Reduce(call);
+
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(), IsNumberFround(IsPlainPrimitiveToNumber(p0)));
+}
+
+// -----------------------------------------------------------------------------
+// Math.imul
+
+TEST_F(JSBuiltinReducerTest, MathImulWithUnsigned32) {
+ Node* function = MathFunction("imul");
+
+ Node* effect = graph()->start();
+ Node* control = graph()->start();
+ Node* context = UndefinedConstant();
+ Node* frame_state = graph()->start();
+ Node* p0 = Parameter(Type::Unsigned32(), 0);
+ Node* p1 = Parameter(Type::Unsigned32(), 1);
+ Node* call = graph()->NewNode(javascript()->CallFunction(4), function,
+ UndefinedConstant(), p0, p1, context,
+ frame_state, effect, control);
+ Reduction r = Reduce(call);
+
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(), IsNumberImul(p0, p1));
+}
+
+TEST_F(JSBuiltinReducerTest, MathImulWithNumber) {
+ Node* function = MathFunction("imul");
+
+ Node* effect = graph()->start();
+ Node* control = graph()->start();
+ Node* context = UndefinedConstant();
+ Node* frame_state = graph()->start();
+ Node* p0 = Parameter(Type::Number(), 0);
+ Node* p1 = Parameter(Type::Number(), 1);
+ Node* call = graph()->NewNode(javascript()->CallFunction(4), function,
+ UndefinedConstant(), p0, p1, context,
+ frame_state, effect, control);
+ Reduction r = Reduce(call);
+
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(),
+ IsNumberImul(IsNumberToUint32(p0), IsNumberToUint32(p1)));
+}
+
+TEST_F(JSBuiltinReducerTest, MathImulWithPlainPrimitive) {
+ Node* function = MathFunction("imul");
+
+ Node* effect = graph()->start();
+ Node* control = graph()->start();
+ Node* context = UndefinedConstant();
+ Node* frame_state = graph()->start();
+ Node* p0 = Parameter(Type::PlainPrimitive(), 0);
+ Node* p1 = Parameter(Type::PlainPrimitive(), 1);
+ Node* call = graph()->NewNode(javascript()->CallFunction(4), function,
+ UndefinedConstant(), p0, p1, context,
+ frame_state, effect, control);
+ Reduction r = Reduce(call);
+
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(),
+ IsNumberImul(IsNumberToUint32(IsPlainPrimitiveToNumber(p0)),
+ IsNumberToUint32(IsPlainPrimitiveToNumber(p1))));
+}
+
+// -----------------------------------------------------------------------------
+// Math.log
+
+TEST_F(JSBuiltinReducerTest, MathLogWithNumber) {
+ Node* function = MathFunction("log");
+
+ Node* effect = graph()->start();
+ Node* control = graph()->start();
+ Node* context = UndefinedConstant();
+ Node* frame_state = graph()->start();
+ TRACED_FOREACH(Type*, t0, kNumberTypes) {
+ Node* p0 = Parameter(t0, 0);
+ Node* call = graph()->NewNode(javascript()->CallFunction(3), function,
+ UndefinedConstant(), p0, context, frame_state,
+ effect, control);
+ Reduction r = Reduce(call);
+
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(), IsNumberLog(p0));
+ }
+}
+
+TEST_F(JSBuiltinReducerTest, MathLogWithPlainPrimitive) {
+ Node* function = MathFunction("log");
+
+ Node* effect = graph()->start();
+ Node* control = graph()->start();
+ Node* context = UndefinedConstant();
+ Node* frame_state = graph()->start();
+ Node* p0 = Parameter(Type::PlainPrimitive(), 0);
+ Node* call = graph()->NewNode(javascript()->CallFunction(3), function,
+ UndefinedConstant(), p0, context, frame_state,
+ effect, control);
+ Reduction r = Reduce(call);
+
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(), IsNumberLog(IsPlainPrimitiveToNumber(p0)));
+}
+
+// -----------------------------------------------------------------------------
+// Math.log1p
+
+TEST_F(JSBuiltinReducerTest, MathLog1pWithNumber) {
+ Node* function = MathFunction("log1p");
+
+ Node* effect = graph()->start();
+ Node* control = graph()->start();
+ Node* context = UndefinedConstant();
+ Node* frame_state = graph()->start();
+ TRACED_FOREACH(Type*, t0, kNumberTypes) {
+ Node* p0 = Parameter(t0, 0);
+ Node* call = graph()->NewNode(javascript()->CallFunction(3), function,
+ UndefinedConstant(), p0, context, frame_state,
+ effect, control);
+ Reduction r = Reduce(call);
+
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(), IsNumberLog1p(p0));
+ }
+}
+
+TEST_F(JSBuiltinReducerTest, MathLog1pWithPlainPrimitive) {
+ Node* function = MathFunction("log1p");
+
+ Node* effect = graph()->start();
+ Node* control = graph()->start();
+ Node* context = UndefinedConstant();
+ Node* frame_state = graph()->start();
+ Node* p0 = Parameter(Type::PlainPrimitive(), 0);
+ Node* call = graph()->NewNode(javascript()->CallFunction(3), function,
+ UndefinedConstant(), p0, context, frame_state,
+ effect, control);
+ Reduction r = Reduce(call);
+
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(), IsNumberLog1p(IsPlainPrimitiveToNumber(p0)));
+}
+
+// -----------------------------------------------------------------------------
// Math.max
-
-TEST_F(JSBuiltinReducerTest, MathMax0) {
+TEST_F(JSBuiltinReducerTest, MathMaxWithNoArguments) {
Node* function = MathFunction("max");
Node* effect = graph()->start();
@@ -86,15 +608,14 @@
Node* frame_state = graph()->start();
Node* call = graph()->NewNode(javascript()->CallFunction(2), function,
UndefinedConstant(), context, frame_state,
- frame_state, effect, control);
+ effect, control);
Reduction r = Reduce(call);
ASSERT_TRUE(r.Changed());
EXPECT_THAT(r.replacement(), IsNumberConstant(-V8_INFINITY));
}
-
-TEST_F(JSBuiltinReducerTest, MathMax1) {
+TEST_F(JSBuiltinReducerTest, MathMaxWithNumber) {
Node* function = MathFunction("max");
Node* effect = graph()->start();
@@ -105,7 +626,7 @@
Node* p0 = Parameter(t0, 0);
Node* call = graph()->NewNode(javascript()->CallFunction(3), function,
UndefinedConstant(), p0, context, frame_state,
- frame_state, effect, control);
+ effect, control);
Reduction r = Reduce(call);
ASSERT_TRUE(r.Changed());
@@ -113,8 +634,24 @@
}
}
+TEST_F(JSBuiltinReducerTest, MathMaxWithPlainPrimitive) {
+ Node* function = MathFunction("max");
-TEST_F(JSBuiltinReducerTest, MathMax2) {
+ Node* effect = graph()->start();
+ Node* control = graph()->start();
+ Node* context = UndefinedConstant();
+ Node* frame_state = graph()->start();
+ Node* p0 = Parameter(Type::PlainPrimitive(), 0);
+ Node* call = graph()->NewNode(javascript()->CallFunction(3), function,
+ UndefinedConstant(), p0, context, frame_state,
+ effect, control);
+ Reduction r = Reduce(call);
+
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(), IsPlainPrimitiveToNumber(p0));
+}
+
+TEST_F(JSBuiltinReducerTest, MathMaxWithIntegral32) {
Node* function = MathFunction("max");
Node* effect = graph()->start();
@@ -127,7 +664,7 @@
Node* p1 = Parameter(t1, 1);
Node* call = graph()->NewNode(javascript()->CallFunction(4), function,
UndefinedConstant(), p0, p1, context,
- frame_state, frame_state, effect, control);
+ frame_state, effect, control);
Reduction r = Reduce(call);
ASSERT_TRUE(r.Changed());
@@ -137,41 +674,27 @@
}
}
-
// -----------------------------------------------------------------------------
-// Math.imul
+// Math.min
-
-TEST_F(JSBuiltinReducerTest, MathImul) {
- Node* function = MathFunction("imul");
+TEST_F(JSBuiltinReducerTest, MathMinWithNoArguments) {
+ Node* function = MathFunction("min");
Node* effect = graph()->start();
Node* control = graph()->start();
Node* context = UndefinedConstant();
Node* frame_state = graph()->start();
- TRACED_FOREACH(Type*, t0, kNumberTypes) {
- TRACED_FOREACH(Type*, t1, kNumberTypes) {
- Node* p0 = Parameter(t0, 0);
- Node* p1 = Parameter(t1, 1);
- Node* call = graph()->NewNode(javascript()->CallFunction(4), function,
- UndefinedConstant(), p0, p1, context,
- frame_state, frame_state, effect, control);
- Reduction r = Reduce(call);
+ Node* call = graph()->NewNode(javascript()->CallFunction(2), function,
+ UndefinedConstant(), context, frame_state,
+ effect, control);
+ Reduction r = Reduce(call);
- ASSERT_TRUE(r.Changed());
- EXPECT_THAT(r.replacement(),
- IsNumberImul(IsNumberToUint32(p0), IsNumberToUint32(p1)));
- }
- }
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(), IsNumberConstant(V8_INFINITY));
}
-
-// -----------------------------------------------------------------------------
-// Math.fround
-
-
-TEST_F(JSBuiltinReducerTest, MathFround) {
- Node* function = MathFunction("fround");
+TEST_F(JSBuiltinReducerTest, MathMinWithNumber) {
+ Node* function = MathFunction("min");
Node* effect = graph()->start();
Node* control = graph()->start();
@@ -181,14 +704,289 @@
Node* p0 = Parameter(t0, 0);
Node* call = graph()->NewNode(javascript()->CallFunction(3), function,
UndefinedConstant(), p0, context, frame_state,
- frame_state, effect, control);
+ effect, control);
Reduction r = Reduce(call);
ASSERT_TRUE(r.Changed());
- EXPECT_THAT(r.replacement(), IsTruncateFloat64ToFloat32(p0));
+ EXPECT_THAT(r.replacement(), p0);
}
}
+TEST_F(JSBuiltinReducerTest, MathMinWithPlainPrimitive) {
+ Node* function = MathFunction("min");
+
+ Node* effect = graph()->start();
+ Node* control = graph()->start();
+ Node* context = UndefinedConstant();
+ Node* frame_state = graph()->start();
+ Node* p0 = Parameter(Type::PlainPrimitive(), 0);
+ Node* call = graph()->NewNode(javascript()->CallFunction(3), function,
+ UndefinedConstant(), p0, context, frame_state,
+ effect, control);
+ Reduction r = Reduce(call);
+
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(), IsPlainPrimitiveToNumber(p0));
+}
+
+TEST_F(JSBuiltinReducerTest, MathMinWithIntegral32) {
+ Node* function = MathFunction("min");
+
+ Node* effect = graph()->start();
+ Node* control = graph()->start();
+ Node* context = UndefinedConstant();
+ Node* frame_state = graph()->start();
+ TRACED_FOREACH(Type*, t0, kIntegral32Types) {
+ TRACED_FOREACH(Type*, t1, kIntegral32Types) {
+ Node* p0 = Parameter(t0, 0);
+ Node* p1 = Parameter(t1, 1);
+ Node* call = graph()->NewNode(javascript()->CallFunction(4), function,
+ UndefinedConstant(), p0, p1, context,
+ frame_state, effect, control);
+ Reduction r = Reduce(call);
+
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(), IsSelect(MachineRepresentation::kNone,
+ IsNumberLessThan(p1, p0), p1, p0));
+ }
+ }
+}
+
+// -----------------------------------------------------------------------------
+// Math.round
+
+TEST_F(JSBuiltinReducerTest, MathRoundWithNumber) {
+ Node* function = MathFunction("round");
+
+ Node* effect = graph()->start();
+ Node* control = graph()->start();
+ Node* context = UndefinedConstant();
+ Node* frame_state = graph()->start();
+ TRACED_FOREACH(Type*, t0, kNumberTypes) {
+ Node* p0 = Parameter(t0, 0);
+ Node* call = graph()->NewNode(javascript()->CallFunction(3), function,
+ UndefinedConstant(), p0, context, frame_state,
+ effect, control);
+ Reduction r = Reduce(call);
+
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(), IsNumberRound(p0));
+ }
+}
+
+TEST_F(JSBuiltinReducerTest, MathRoundWithPlainPrimitive) {
+ Node* function = MathFunction("round");
+
+ Node* effect = graph()->start();
+ Node* control = graph()->start();
+ Node* context = UndefinedConstant();
+ Node* frame_state = graph()->start();
+ Node* p0 = Parameter(Type::PlainPrimitive(), 0);
+ Node* call = graph()->NewNode(javascript()->CallFunction(3), function,
+ UndefinedConstant(), p0, context, frame_state,
+ effect, control);
+ Reduction r = Reduce(call);
+
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(), IsNumberRound(IsPlainPrimitiveToNumber(p0)));
+}
+
+// -----------------------------------------------------------------------------
+// Math.sin
+
+TEST_F(JSBuiltinReducerTest, MathSinWithNumber) {
+ Node* function = MathFunction("sin");
+
+ Node* effect = graph()->start();
+ Node* control = graph()->start();
+ Node* context = UndefinedConstant();
+ Node* frame_state = graph()->start();
+ TRACED_FOREACH(Type*, t0, kNumberTypes) {
+ Node* p0 = Parameter(t0, 0);
+ Node* call = graph()->NewNode(javascript()->CallFunction(3), function,
+ UndefinedConstant(), p0, context, frame_state,
+ effect, control);
+ Reduction r = Reduce(call);
+
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(), IsNumberSin(p0));
+ }
+}
+
+TEST_F(JSBuiltinReducerTest, MathSinWithPlainPrimitive) {
+ Node* function = MathFunction("sin");
+
+ Node* effect = graph()->start();
+ Node* control = graph()->start();
+ Node* context = UndefinedConstant();
+ Node* frame_state = graph()->start();
+ Node* p0 = Parameter(Type::PlainPrimitive(), 0);
+ Node* call = graph()->NewNode(javascript()->CallFunction(3), function,
+ UndefinedConstant(), p0, context, frame_state,
+ effect, control);
+ Reduction r = Reduce(call);
+
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(), IsNumberSin(IsPlainPrimitiveToNumber(p0)));
+}
+
+// -----------------------------------------------------------------------------
+// Math.sqrt
+
+TEST_F(JSBuiltinReducerTest, MathSqrtWithNumber) {
+ Node* function = MathFunction("sqrt");
+
+ Node* effect = graph()->start();
+ Node* control = graph()->start();
+ Node* context = UndefinedConstant();
+ Node* frame_state = graph()->start();
+ TRACED_FOREACH(Type*, t0, kNumberTypes) {
+ Node* p0 = Parameter(t0, 0);
+ Node* call = graph()->NewNode(javascript()->CallFunction(3), function,
+ UndefinedConstant(), p0, context, frame_state,
+ effect, control);
+ Reduction r = Reduce(call);
+
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(), IsNumberSqrt(p0));
+ }
+}
+
+TEST_F(JSBuiltinReducerTest, MathSqrtWithPlainPrimitive) {
+ Node* function = MathFunction("sqrt");
+
+ Node* effect = graph()->start();
+ Node* control = graph()->start();
+ Node* context = UndefinedConstant();
+ Node* frame_state = graph()->start();
+ Node* p0 = Parameter(Type::PlainPrimitive(), 0);
+ Node* call = graph()->NewNode(javascript()->CallFunction(3), function,
+ UndefinedConstant(), p0, context, frame_state,
+ effect, control);
+ Reduction r = Reduce(call);
+
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(), IsNumberSqrt(IsPlainPrimitiveToNumber(p0)));
+}
+
+// -----------------------------------------------------------------------------
+// Math.tan
+
+TEST_F(JSBuiltinReducerTest, MathTanWithNumber) {
+ Node* function = MathFunction("tan");
+
+ Node* effect = graph()->start();
+ Node* control = graph()->start();
+ Node* context = UndefinedConstant();
+ Node* frame_state = graph()->start();
+ TRACED_FOREACH(Type*, t0, kNumberTypes) {
+ Node* p0 = Parameter(t0, 0);
+ Node* call = graph()->NewNode(javascript()->CallFunction(3), function,
+ UndefinedConstant(), p0, context, frame_state,
+ effect, control);
+ Reduction r = Reduce(call);
+
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(), IsNumberTan(p0));
+ }
+}
+
+TEST_F(JSBuiltinReducerTest, MathTanWithPlainPrimitive) {
+ Node* function = MathFunction("tan");
+
+ Node* effect = graph()->start();
+ Node* control = graph()->start();
+ Node* context = UndefinedConstant();
+ Node* frame_state = graph()->start();
+ Node* p0 = Parameter(Type::PlainPrimitive(), 0);
+ Node* call = graph()->NewNode(javascript()->CallFunction(3), function,
+ UndefinedConstant(), p0, context, frame_state,
+ effect, control);
+ Reduction r = Reduce(call);
+
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(), IsNumberTan(IsPlainPrimitiveToNumber(p0)));
+}
+
+// -----------------------------------------------------------------------------
+// Math.trunc
+
+TEST_F(JSBuiltinReducerTest, MathTruncWithNumber) {
+ Node* function = MathFunction("trunc");
+
+ Node* effect = graph()->start();
+ Node* control = graph()->start();
+ Node* context = UndefinedConstant();
+ Node* frame_state = graph()->start();
+ TRACED_FOREACH(Type*, t0, kNumberTypes) {
+ Node* p0 = Parameter(t0, 0);
+ Node* call = graph()->NewNode(javascript()->CallFunction(3), function,
+ UndefinedConstant(), p0, context, frame_state,
+ effect, control);
+ Reduction r = Reduce(call);
+
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(), IsNumberTrunc(p0));
+ }
+}
+
+TEST_F(JSBuiltinReducerTest, MathTruncWithPlainPrimitive) {
+ Node* function = MathFunction("trunc");
+
+ Node* effect = graph()->start();
+ Node* control = graph()->start();
+ Node* context = UndefinedConstant();
+ Node* frame_state = graph()->start();
+ Node* p0 = Parameter(Type::PlainPrimitive(), 0);
+ Node* call = graph()->NewNode(javascript()->CallFunction(3), function,
+ UndefinedConstant(), p0, context, frame_state,
+ effect, control);
+ Reduction r = Reduce(call);
+
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(), IsNumberTrunc(IsPlainPrimitiveToNumber(p0)));
+}
+
+// -----------------------------------------------------------------------------
+// String.fromCharCode
+
+TEST_F(JSBuiltinReducerTest, StringFromCharCodeWithNumber) {
+ Node* function = StringFunction("fromCharCode");
+
+ Node* effect = graph()->start();
+ Node* control = graph()->start();
+ Node* context = UndefinedConstant();
+ Node* frame_state = graph()->start();
+ TRACED_FOREACH(Type*, t0, kNumberTypes) {
+ Node* p0 = Parameter(t0, 0);
+ Node* call = graph()->NewNode(javascript()->CallFunction(3), function,
+ UndefinedConstant(), p0, context, frame_state,
+ effect, control);
+ Reduction r = Reduce(call);
+
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(), IsStringFromCharCode(p0));
+ }
+}
+
+TEST_F(JSBuiltinReducerTest, StringFromCharCodeWithPlainPrimitive) {
+ Node* function = StringFunction("fromCharCode");
+
+ Node* effect = graph()->start();
+ Node* control = graph()->start();
+ Node* context = UndefinedConstant();
+ Node* frame_state = graph()->start();
+ Node* p0 = Parameter(Type::PlainPrimitive(), 0);
+ Node* call = graph()->NewNode(javascript()->CallFunction(3), function,
+ UndefinedConstant(), p0, context, frame_state,
+ effect, control);
+ Reduction r = Reduce(call);
+
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(),
+ IsStringFromCharCode(IsPlainPrimitiveToNumber(p0)));
+}
+
} // namespace compiler
} // namespace internal
} // namespace v8
diff --git a/test/unittests/compiler/js-create-lowering-unittest.cc b/test/unittests/compiler/js-create-lowering-unittest.cc
index 5d95d0d..6e6245d 100644
--- a/test/unittests/compiler/js-create-lowering-unittest.cc
+++ b/test/unittests/compiler/js-create-lowering-unittest.cc
@@ -139,7 +139,7 @@
Node* const context = UndefinedConstant();
Node* const effect = graph()->start();
Node* const control = graph()->start();
- Handle<SharedFunctionInfo> shared(isolate()->object_function()->shared());
+ Handle<SharedFunctionInfo> shared(isolate()->number_function()->shared());
Reduction r =
Reduce(graph()->NewNode(javascript()->CreateClosure(shared, NOT_TENURED),
context, effect, control));
diff --git a/test/unittests/compiler/js-intrinsic-lowering-unittest.cc b/test/unittests/compiler/js-intrinsic-lowering-unittest.cc
index 7c2f459..7024559 100644
--- a/test/unittests/compiler/js-intrinsic-lowering-unittest.cc
+++ b/test/unittests/compiler/js-intrinsic-lowering-unittest.cc
@@ -43,13 +43,6 @@
return reducer.Reduce(node);
}
- Node* EmptyFrameState() {
- MachineOperatorBuilder machine(zone());
- JSGraph jsgraph(isolate(), graph(), common(), javascript(), nullptr,
- &machine);
- return jsgraph.EmptyFrameState();
- }
-
JSOperatorBuilder* javascript() { return &javascript_; }
private:
@@ -58,27 +51,6 @@
// -----------------------------------------------------------------------------
-// %_ConstructDouble
-
-
-TEST_F(JSIntrinsicLoweringTest, InlineOptimizedConstructDouble) {
- Node* const input0 = Parameter(0);
- Node* const input1 = Parameter(1);
- Node* const context = Parameter(2);
- Node* const effect = graph()->start();
- Node* const control = graph()->start();
- Reduction const r = Reduce(graph()->NewNode(
- javascript()->CallRuntime(Runtime::kInlineConstructDouble, 2), input0,
- input1, context, effect, control));
- ASSERT_TRUE(r.Changed());
- EXPECT_THAT(r.replacement(), IsFloat64InsertHighWord32(
- IsFloat64InsertLowWord32(
- IsNumberConstant(BitEq(0.0)), input1),
- input0));
-}
-
-
-// -----------------------------------------------------------------------------
// %_DoubleLo
diff --git a/test/unittests/compiler/js-operator-unittest.cc b/test/unittests/compiler/js-operator-unittest.cc
index 28df6a9..d5f30ef 100644
--- a/test/unittests/compiler/js-operator-unittest.cc
+++ b/test/unittests/compiler/js-operator-unittest.cc
@@ -40,22 +40,12 @@
control_input_count, value_output_count, effect_output_count, \
control_output_count \
}
- SHARED(Equal, Operator::kNoProperties, 2, 1, 1, 1, 1, 1, 2),
- SHARED(NotEqual, Operator::kNoProperties, 2, 1, 1, 1, 1, 1, 2),
- SHARED(StrictEqual, Operator::kPure, 2, 0, 0, 0, 1, 0, 0),
- SHARED(StrictNotEqual, Operator::kPure, 2, 0, 0, 0, 1, 0, 0),
- SHARED(LessThan, Operator::kNoProperties, 2, 2, 1, 1, 1, 1, 2),
- SHARED(GreaterThan, Operator::kNoProperties, 2, 2, 1, 1, 1, 1, 2),
- SHARED(LessThanOrEqual, Operator::kNoProperties, 2, 2, 1, 1, 1, 1, 2),
- SHARED(GreaterThanOrEqual, Operator::kNoProperties, 2, 2, 1, 1, 1, 1, 2),
SHARED(ToNumber, Operator::kNoProperties, 1, 1, 1, 1, 1, 1, 2),
SHARED(ToString, Operator::kNoProperties, 1, 1, 1, 1, 1, 1, 2),
SHARED(ToName, Operator::kNoProperties, 1, 1, 1, 1, 1, 1, 2),
SHARED(ToObject, Operator::kFoldable, 1, 1, 1, 1, 1, 1, 2),
SHARED(Create, Operator::kEliminatable, 2, 1, 1, 0, 1, 1, 0),
- SHARED(HasProperty, Operator::kNoProperties, 2, 1, 1, 1, 1, 1, 2),
SHARED(TypeOf, Operator::kPure, 1, 0, 0, 0, 1, 0, 0),
- SHARED(InstanceOf, Operator::kNoProperties, 2, 1, 1, 1, 1, 1, 2),
SHARED(CreateWithContext, Operator::kNoProperties, 2, 0, 1, 1, 1, 1, 2),
SHARED(CreateModuleContext, Operator::kNoProperties, 2, 0, 1, 1, 1, 1, 2),
#undef SHARED
diff --git a/test/unittests/compiler/js-typed-lowering-unittest.cc b/test/unittests/compiler/js-typed-lowering-unittest.cc
index 904d5f7..3a8e778 100644
--- a/test/unittests/compiler/js-typed-lowering-unittest.cc
+++ b/test/unittests/compiler/js-typed-lowering-unittest.cc
@@ -87,8 +87,9 @@
// TODO(titzer): mock the GraphReducer here for better unit testing.
GraphReducer graph_reducer(zone(), graph());
JSTypedLowering reducer(&graph_reducer, &deps_,
- JSTypedLowering::kDeoptimizationEnabled, &jsgraph,
- zone());
+ JSTypedLowering::kDeoptimizationEnabled |
+ JSTypedLowering::kTypeFeedbackEnabled,
+ &jsgraph, zone());
return reducer.Reduce(node);
}
@@ -320,8 +321,7 @@
Reduce(graph()->NewNode(javascript()->ToNumber(), input, context,
EmptyFrameState(), effect, control));
ASSERT_TRUE(r.Changed());
- EXPECT_THAT(r.replacement(), IsToNumber(input, IsNumberConstant(BitEq(0.0)),
- graph()->start(), control));
+ EXPECT_THAT(r.replacement(), IsPlainPrimitiveToNumber(input));
}
@@ -384,8 +384,9 @@
Node* const context = UndefinedConstant();
TRACED_FOREACH(Type*, type, kJSTypes) {
Node* const lhs = Parameter(type);
- Reduction r = Reduce(
- graph()->NewNode(javascript()->StrictEqual(), lhs, the_hole, context));
+ Reduction r = Reduce(graph()->NewNode(
+ javascript()->StrictEqual(CompareOperationHints::Any()), lhs, the_hole,
+ context));
ASSERT_TRUE(r.Changed());
EXPECT_THAT(r.replacement(), IsFalseConstant());
}
@@ -396,8 +397,9 @@
Node* const lhs = Parameter(Type::Unique(), 0);
Node* const rhs = Parameter(Type::Unique(), 1);
Node* const context = Parameter(Type::Any(), 2);
- Reduction r =
- Reduce(graph()->NewNode(javascript()->StrictEqual(), lhs, rhs, context));
+ Reduction r = Reduce(
+ graph()->NewNode(javascript()->StrictEqual(CompareOperationHints::Any()),
+ lhs, rhs, context));
ASSERT_TRUE(r.Changed());
EXPECT_THAT(r.replacement(), IsReferenceEqual(Type::Unique(), lhs, rhs));
}
@@ -602,9 +604,9 @@
Node* context = UndefinedConstant();
Node* effect = graph()->start();
Node* control = graph()->start();
- Reduction r = Reduce(graph()->NewNode(
- javascript()->LoadProperty(feedback), base, key, vector, context,
- EmptyFrameState(), EmptyFrameState(), effect, control));
+ Reduction r = Reduce(graph()->NewNode(javascript()->LoadProperty(feedback),
+ base, key, vector, context,
+ EmptyFrameState(), effect, control));
Matcher<Node*> offset_matcher =
element_size == 1
@@ -643,9 +645,9 @@
Node* context = UndefinedConstant();
Node* effect = graph()->start();
Node* control = graph()->start();
- Reduction r = Reduce(graph()->NewNode(
- javascript()->LoadProperty(feedback), base, key, vector, context,
- EmptyFrameState(), EmptyFrameState(), effect, control));
+ Reduction r = Reduce(graph()->NewNode(javascript()->LoadProperty(feedback),
+ base, key, vector, context,
+ EmptyFrameState(), effect, control));
ASSERT_TRUE(r.Changed());
EXPECT_THAT(
@@ -684,8 +686,7 @@
VectorSlotPair feedback;
const Operator* op = javascript()->StoreProperty(language_mode, feedback);
Node* node = graph()->NewNode(op, base, key, value, vector, context,
- EmptyFrameState(), EmptyFrameState(),
- effect, control);
+ EmptyFrameState(), effect, control);
Reduction r = Reduce(node);
Matcher<Node*> offset_matcher =
@@ -725,11 +726,14 @@
Node* context = UndefinedConstant();
Node* effect = graph()->start();
Node* control = graph()->start();
+ // TODO(mstarzinger): Once the effect-control-linearizer provides a frame
+ // state we can get rid of this checkpoint again. The reducer won't care.
+ Node* checkpoint = graph()->NewNode(common()->Checkpoint(),
+ EmptyFrameState(), effect, control);
VectorSlotPair feedback;
const Operator* op = javascript()->StoreProperty(language_mode, feedback);
Node* node = graph()->NewNode(op, base, key, value, vector, context,
- EmptyFrameState(), EmptyFrameState(),
- effect, control);
+ EmptyFrameState(), checkpoint, control);
Reduction r = Reduce(node);
Matcher<Node*> offset_matcher =
@@ -738,7 +742,7 @@
: IsWord32Shl(key, IsInt32Constant(WhichPowerOf2(element_size)));
Matcher<Node*> value_matcher =
- IsToNumber(value, context, effect, control);
+ IsToNumber(value, context, checkpoint, control);
Matcher<Node*> effect_matcher = value_matcher;
ASSERT_TRUE(r.Changed());
@@ -778,8 +782,7 @@
VectorSlotPair feedback;
const Operator* op = javascript()->StoreProperty(language_mode, feedback);
Node* node = graph()->NewNode(op, base, key, value, vector, context,
- EmptyFrameState(), EmptyFrameState(),
- effect, control);
+ EmptyFrameState(), effect, control);
Reduction r = Reduce(node);
ASSERT_TRUE(r.Changed());
@@ -805,9 +808,9 @@
Node* const context = UndefinedConstant();
Node* const effect = graph()->start();
Node* const control = graph()->start();
- Reduction const r = Reduce(graph()->NewNode(
- javascript()->LoadNamed(name, feedback), receiver, vector, context,
- EmptyFrameState(), EmptyFrameState(), effect, control));
+ Reduction const r = Reduce(
+ graph()->NewNode(javascript()->LoadNamed(name, feedback), receiver,
+ vector, context, EmptyFrameState(), effect, control));
ASSERT_TRUE(r.Changed());
EXPECT_THAT(r.replacement(), IsLoadField(AccessBuilder::ForStringLength(),
receiver, effect, control));
@@ -838,6 +841,52 @@
lhs, rhs, context, frame_state0, effect, control));
}
+TEST_F(JSTypedLoweringTest, JSAddSmis) {
+ BinaryOperationHints const hints(BinaryOperationHints::kSignedSmall,
+ BinaryOperationHints::kSignedSmall,
+ BinaryOperationHints::kSignedSmall);
+ TRACED_FOREACH(LanguageMode, language_mode, kLanguageModes) {
+ Node* lhs = Parameter(Type::Number(), 0);
+ Node* rhs = Parameter(Type::Number(), 1);
+ Node* context = Parameter(Type::Any(), 2);
+ Node* frame_state0 = EmptyFrameState();
+ Node* frame_state1 = EmptyFrameState();
+ Node* effect = graph()->start();
+ Node* control = graph()->start();
+ Reduction r =
+ Reduce(graph()->NewNode(javascript()->Add(hints), lhs, rhs, context,
+ frame_state0, frame_state1, effect, control));
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(),
+ IsSpeculativeNumberAdd(BinaryOperationHints::kSignedSmall, lhs,
+ rhs, effect, control));
+ }
+}
+
+// -----------------------------------------------------------------------------
+// JSSubtract
+
+TEST_F(JSTypedLoweringTest, JSSubtractSmis) {
+ BinaryOperationHints const hints(BinaryOperationHints::kSignedSmall,
+ BinaryOperationHints::kSignedSmall,
+ BinaryOperationHints::kSignedSmall);
+ TRACED_FOREACH(LanguageMode, language_mode, kLanguageModes) {
+ Node* lhs = Parameter(Type::Number(), 0);
+ Node* rhs = Parameter(Type::Number(), 1);
+ Node* context = Parameter(Type::Any(), 2);
+ Node* frame_state0 = EmptyFrameState();
+ Node* frame_state1 = EmptyFrameState();
+ Node* effect = graph()->start();
+ Node* control = graph()->start();
+ Reduction r = Reduce(graph()->NewNode(javascript()->Subtract(hints), lhs,
+ rhs, context, frame_state0,
+ frame_state1, effect, control));
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(),
+ IsSpeculativeNumberSubtract(BinaryOperationHints::kSignedSmall,
+ lhs, rhs, effect, control));
+ }
+}
// -----------------------------------------------------------------------------
// JSInstanceOf
diff --git a/test/unittests/compiler/machine-operator-reducer-unittest.cc b/test/unittests/compiler/machine-operator-reducer-unittest.cc
index 8b65e04..05156ed 100644
--- a/test/unittests/compiler/machine-operator-reducer-unittest.cc
+++ b/test/unittests/compiler/machine-operator-reducer-unittest.cc
@@ -2,10 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "src/compiler/machine-operator-reducer.h"
#include "src/base/bits.h"
#include "src/base/division-by-constant.h"
+#include "src/base/ieee754.h"
#include "src/compiler/js-graph.h"
-#include "src/compiler/machine-operator-reducer.h"
#include "src/compiler/typer.h"
#include "src/conversions-inl.h"
#include "test/unittests/compiler/graph-unittest.h"
@@ -16,6 +17,7 @@
using testing::BitEq;
using testing::Capture;
using testing::CaptureEq;
+using testing::NanSensitiveDoubleEq;
namespace v8 {
namespace internal {
@@ -848,8 +850,24 @@
// -----------------------------------------------------------------------------
-// Word32Shl
+// Word32Shr
+TEST_F(MachineOperatorReducerTest, Word32ShrWithWord32And) {
+ Node* const p0 = Parameter(0);
+ TRACED_FORRANGE(int32_t, shift, 1, 31) {
+ uint32_t mask = (1 << shift) - 1;
+ Node* node = graph()->NewNode(
+ machine()->Word32Shr(),
+ graph()->NewNode(machine()->Word32And(), p0, Int32Constant(mask)),
+ Int32Constant(shift));
+ Reduction r = Reduce(node);
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(), IsInt32Constant(0));
+ }
+}
+
+// -----------------------------------------------------------------------------
+// Word32Shl
TEST_F(MachineOperatorReducerTest, Word32ShlWithZeroShift) {
Node* p0 = Parameter(0);
@@ -1266,28 +1284,31 @@
TEST_F(MachineOperatorReducerTest, Int32AddWithOverflowWithZero) {
+ Node* control = graph()->start();
Node* p0 = Parameter(0);
{
Node* add = graph()->NewNode(machine()->Int32AddWithOverflow(),
- Int32Constant(0), p0);
+ Int32Constant(0), p0, control);
- Reduction r = Reduce(graph()->NewNode(common()->Projection(1), add));
+ Reduction r =
+ Reduce(graph()->NewNode(common()->Projection(1), add, control));
ASSERT_TRUE(r.Changed());
EXPECT_THAT(r.replacement(), IsInt32Constant(0));
- r = Reduce(graph()->NewNode(common()->Projection(0), add));
+ r = Reduce(graph()->NewNode(common()->Projection(0), add, control));
ASSERT_TRUE(r.Changed());
EXPECT_EQ(p0, r.replacement());
}
{
Node* add = graph()->NewNode(machine()->Int32AddWithOverflow(), p0,
- Int32Constant(0));
+ Int32Constant(0), control);
- Reduction r = Reduce(graph()->NewNode(common()->Projection(1), add));
+ Reduction r =
+ Reduce(graph()->NewNode(common()->Projection(1), add, control));
ASSERT_TRUE(r.Changed());
EXPECT_THAT(r.replacement(), IsInt32Constant(0));
- r = Reduce(graph()->NewNode(common()->Projection(0), add));
+ r = Reduce(graph()->NewNode(common()->Projection(0), add, control));
ASSERT_TRUE(r.Changed());
EXPECT_EQ(p0, r.replacement());
}
@@ -1295,18 +1316,20 @@
TEST_F(MachineOperatorReducerTest, Int32AddWithOverflowWithConstant) {
+ Node* control = graph()->start();
TRACED_FOREACH(int32_t, x, kInt32Values) {
TRACED_FOREACH(int32_t, y, kInt32Values) {
int32_t z;
Node* add = graph()->NewNode(machine()->Int32AddWithOverflow(),
- Int32Constant(x), Int32Constant(y));
+ Int32Constant(x), Int32Constant(y), control);
- Reduction r = Reduce(graph()->NewNode(common()->Projection(1), add));
+ Reduction r =
+ Reduce(graph()->NewNode(common()->Projection(1), add, control));
ASSERT_TRUE(r.Changed());
EXPECT_THAT(r.replacement(),
IsInt32Constant(base::bits::SignedAddOverflow32(x, y, &z)));
- r = Reduce(graph()->NewNode(common()->Projection(0), add));
+ r = Reduce(graph()->NewNode(common()->Projection(0), add, control));
ASSERT_TRUE(r.Changed());
EXPECT_THAT(r.replacement(), IsInt32Constant(z));
}
@@ -1319,33 +1342,36 @@
TEST_F(MachineOperatorReducerTest, Int32SubWithOverflowWithZero) {
+ Node* control = graph()->start();
Node* p0 = Parameter(0);
- Node* add =
- graph()->NewNode(machine()->Int32SubWithOverflow(), p0, Int32Constant(0));
+ Node* add = graph()->NewNode(machine()->Int32SubWithOverflow(), p0,
+ Int32Constant(0), control);
- Reduction r = Reduce(graph()->NewNode(common()->Projection(1), add));
+ Reduction r = Reduce(graph()->NewNode(common()->Projection(1), add, control));
ASSERT_TRUE(r.Changed());
EXPECT_THAT(r.replacement(), IsInt32Constant(0));
- r = Reduce(graph()->NewNode(common()->Projection(0), add));
+ r = Reduce(graph()->NewNode(common()->Projection(0), add, control));
ASSERT_TRUE(r.Changed());
EXPECT_EQ(p0, r.replacement());
}
TEST_F(MachineOperatorReducerTest, Int32SubWithOverflowWithConstant) {
+ Node* control = graph()->start();
TRACED_FOREACH(int32_t, x, kInt32Values) {
TRACED_FOREACH(int32_t, y, kInt32Values) {
int32_t z;
Node* add = graph()->NewNode(machine()->Int32SubWithOverflow(),
- Int32Constant(x), Int32Constant(y));
+ Int32Constant(x), Int32Constant(y), control);
- Reduction r = Reduce(graph()->NewNode(common()->Projection(1), add));
+ Reduction r =
+ Reduce(graph()->NewNode(common()->Projection(1), add, control));
ASSERT_TRUE(r.Changed());
EXPECT_THAT(r.replacement(),
IsInt32Constant(base::bits::SignedSubOverflow32(x, y, &z)));
- r = Reduce(graph()->NewNode(common()->Projection(0), add));
+ r = Reduce(graph()->NewNode(common()->Projection(0), add, control));
ASSERT_TRUE(r.Changed());
EXPECT_THAT(r.replacement(), IsInt32Constant(z));
}
@@ -1399,8 +1425,133 @@
// -----------------------------------------------------------------------------
-// Float64InsertLowWord32
+// Float64Atan
+TEST_F(MachineOperatorReducerTest, Float64AtanWithConstant) {
+ TRACED_FOREACH(double, x, kFloat64Values) {
+ Reduction const r =
+ Reduce(graph()->NewNode(machine()->Float64Atan(), Float64Constant(x)));
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(
+ r.replacement(),
+ IsFloat64Constant(NanSensitiveDoubleEq(base::ieee754::atan(x))));
+ }
+}
+
+// -----------------------------------------------------------------------------
+// Float64Atan2
+
+TEST_F(MachineOperatorReducerTest, Float64Atan2WithConstant) {
+ TRACED_FOREACH(double, y, kFloat64Values) {
+ TRACED_FOREACH(double, x, kFloat64Values) {
+ Reduction const r = Reduce(graph()->NewNode(
+ machine()->Float64Atan2(), Float64Constant(y), Float64Constant(x)));
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(
+ r.replacement(),
+ IsFloat64Constant(NanSensitiveDoubleEq(base::ieee754::atan2(y, x))));
+ }
+ }
+}
+
+TEST_F(MachineOperatorReducerTest, Float64Atan2WithNaN) {
+ Node* const p0 = Parameter(0);
+ Node* const nan = Float64Constant(std::numeric_limits<double>::quiet_NaN());
+ {
+ Reduction const r =
+ Reduce(graph()->NewNode(machine()->Float64Atan2(), p0, nan));
+ ASSERT_TRUE(r.Changed());
+ EXPECT_EQ(nan, r.replacement());
+ }
+ {
+ Reduction const r =
+ Reduce(graph()->NewNode(machine()->Float64Atan2(), nan, p0));
+ ASSERT_TRUE(r.Changed());
+ EXPECT_EQ(nan, r.replacement());
+ }
+}
+
+// -----------------------------------------------------------------------------
+// Float64Cos
+
+TEST_F(MachineOperatorReducerTest, Float64CosWithConstant) {
+ TRACED_FOREACH(double, x, kFloat64Values) {
+ Reduction const r =
+ Reduce(graph()->NewNode(machine()->Float64Cos(), Float64Constant(x)));
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(),
+ IsFloat64Constant(NanSensitiveDoubleEq(base::ieee754::cos(x))));
+ }
+}
+
+// -----------------------------------------------------------------------------
+// Float64Exp
+
+TEST_F(MachineOperatorReducerTest, Float64ExpWithConstant) {
+ TRACED_FOREACH(double, x, kFloat64Values) {
+ Reduction const r =
+ Reduce(graph()->NewNode(machine()->Float64Exp(), Float64Constant(x)));
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(),
+ IsFloat64Constant(NanSensitiveDoubleEq(base::ieee754::exp(x))));
+ }
+}
+
+// -----------------------------------------------------------------------------
+// Float64Log
+
+TEST_F(MachineOperatorReducerTest, Float64LogWithConstant) {
+ TRACED_FOREACH(double, x, kFloat64Values) {
+ Reduction const r =
+ Reduce(graph()->NewNode(machine()->Float64Log(), Float64Constant(x)));
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(),
+ IsFloat64Constant(NanSensitiveDoubleEq(base::ieee754::log(x))));
+ }
+}
+
+// -----------------------------------------------------------------------------
+// Float64Log1p
+
+TEST_F(MachineOperatorReducerTest, Float64Log1pWithConstant) {
+ TRACED_FOREACH(double, x, kFloat64Values) {
+ Reduction const r =
+ Reduce(graph()->NewNode(machine()->Float64Log1p(), Float64Constant(x)));
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(
+ r.replacement(),
+ IsFloat64Constant(NanSensitiveDoubleEq(base::ieee754::log1p(x))));
+ }
+}
+
+// -----------------------------------------------------------------------------
+// Float64Sin
+
+TEST_F(MachineOperatorReducerTest, Float64SinWithConstant) {
+ TRACED_FOREACH(double, x, kFloat64Values) {
+ Reduction const r =
+ Reduce(graph()->NewNode(machine()->Float64Sin(), Float64Constant(x)));
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(),
+ IsFloat64Constant(NanSensitiveDoubleEq(base::ieee754::sin(x))));
+ }
+}
+
+// -----------------------------------------------------------------------------
+// Float64Tan
+
+TEST_F(MachineOperatorReducerTest, Float64TanWithConstant) {
+ TRACED_FOREACH(double, x, kFloat64Values) {
+ Reduction const r =
+ Reduce(graph()->NewNode(machine()->Float64Tan(), Float64Constant(x)));
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(),
+ IsFloat64Constant(NanSensitiveDoubleEq(base::ieee754::tan(x))));
+ }
+}
+
+// -----------------------------------------------------------------------------
+// Float64InsertLowWord32
TEST_F(MachineOperatorReducerTest, Float64InsertLowWord32WithConstant) {
TRACED_FOREACH(double, x, kFloat64Values) {
diff --git a/test/unittests/compiler/machine-operator-unittest.cc b/test/unittests/compiler/machine-operator-unittest.cc
index 59eb484..4367705 100644
--- a/test/unittests/compiler/machine-operator-unittest.cc
+++ b/test/unittests/compiler/machine-operator-unittest.cc
@@ -208,9 +208,7 @@
PURE(Word64Ror, 2, 0, 1), // --
PURE(Word64Equal, 2, 0, 1), // --
PURE(Int32Add, 2, 0, 1), // --
- PURE(Int32AddWithOverflow, 2, 0, 2), // --
PURE(Int32Sub, 2, 0, 1), // --
- PURE(Int32SubWithOverflow, 2, 0, 2), // --
PURE(Int32Mul, 2, 0, 1), // --
PURE(Int32MulHigh, 2, 0, 1), // --
PURE(Int32Div, 2, 1, 1), // --
@@ -327,6 +325,8 @@
OPTIONAL_ENTRY(Float64RoundDown, 1, 0, 1), // --
OPTIONAL_ENTRY(Float64RoundTruncate, 1, 0, 1), // --
OPTIONAL_ENTRY(Float64RoundTiesAway, 1, 0, 1), // --
+ OPTIONAL_ENTRY(Float32Neg, 1, 0, 1), // --
+ OPTIONAL_ENTRY(Float64Neg, 1, 0, 1), // --
#undef OPTIONAL_ENTRY
};
} // namespace
diff --git a/test/unittests/compiler/move-optimizer-unittest.cc b/test/unittests/compiler/move-optimizer-unittest.cc
index 5ccd0c6..4c69384 100644
--- a/test/unittests/compiler/move-optimizer-unittest.cc
+++ b/test/unittests/compiler/move-optimizer-unittest.cc
@@ -106,11 +106,9 @@
TEST_F(MoveOptimizerTest, RemovesRedundantExplicit) {
int first_reg_index =
- RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN)
- ->GetAllocatableGeneralCode(0);
+ RegisterConfiguration::Turbofan()->GetAllocatableGeneralCode(0);
int second_reg_index =
- RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN)
- ->GetAllocatableGeneralCode(1);
+ RegisterConfiguration::Turbofan()->GetAllocatableGeneralCode(1);
StartBlock();
auto first_instr = EmitNop();
diff --git a/test/unittests/compiler/node-test-utils.cc b/test/unittests/compiler/node-test-utils.cc
index 6adacc1..e700080 100644
--- a/test/unittests/compiler/node-test-utils.cc
+++ b/test/unittests/compiler/node-test-utils.cc
@@ -800,6 +800,40 @@
const Matcher<Node*> rhs_matcher_;
};
+class IsSpeculativeBinopMatcher final : public NodeMatcher {
+ public:
+ IsSpeculativeBinopMatcher(
+ IrOpcode::Value opcode,
+ const Matcher<BinaryOperationHints::Hint>& hint_matcher,
+ const Matcher<Node*>& lhs_matcher, const Matcher<Node*>& rhs_matcher,
+ const Matcher<Node*>& effect_matcher,
+ const Matcher<Node*>& control_matcher)
+ : NodeMatcher(opcode),
+ lhs_matcher_(lhs_matcher),
+ rhs_matcher_(rhs_matcher),
+ effect_matcher_(effect_matcher),
+ control_matcher_(control_matcher) {}
+
+ bool MatchAndExplain(Node* node, MatchResultListener* listener) const final {
+ return (NodeMatcher::MatchAndExplain(node, listener) &&
+ // TODO(bmeurer): The type parameter is currently ignored.
+ PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "lhs",
+ lhs_matcher_, listener) &&
+ PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1), "rhs",
+ rhs_matcher_, listener) &&
+ PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect",
+ effect_matcher_, listener) &&
+ PrintMatchAndExplain(NodeProperties::GetControlInput(node),
+ "control", control_matcher_, listener));
+ }
+
+ private:
+ const Matcher<Type*> type_matcher_;
+ const Matcher<Node*> lhs_matcher_;
+ const Matcher<Node*> rhs_matcher_;
+ const Matcher<Node*> effect_matcher_;
+ const Matcher<Node*> control_matcher_;
+};
class IsAllocateMatcher final : public NodeMatcher {
public:
@@ -2029,6 +2063,25 @@
new IsReferenceEqualMatcher(type_matcher, lhs_matcher, rhs_matcher));
}
+Matcher<Node*> IsSpeculativeNumberAdd(
+ const Matcher<BinaryOperationHints::Hint>& hint_matcher,
+ const Matcher<Node*>& lhs_matcher, const Matcher<Node*>& rhs_matcher,
+ const Matcher<Node*>& effect_matcher,
+ const Matcher<Node*>& control_matcher) {
+ return MakeMatcher(new IsSpeculativeBinopMatcher(
+ IrOpcode::kSpeculativeNumberAdd, hint_matcher, lhs_matcher, rhs_matcher,
+ effect_matcher, control_matcher));
+}
+
+Matcher<Node*> IsSpeculativeNumberSubtract(
+ const Matcher<BinaryOperationHints::Hint>& hint_matcher,
+ const Matcher<Node*>& lhs_matcher, const Matcher<Node*>& rhs_matcher,
+ const Matcher<Node*>& effect_matcher,
+ const Matcher<Node*>& control_matcher) {
+ return MakeMatcher(new IsSpeculativeBinopMatcher(
+ IrOpcode::kSpeculativeNumberSubtract, hint_matcher, lhs_matcher,
+ rhs_matcher, effect_matcher, control_matcher));
+}
Matcher<Node*> IsAllocate(const Matcher<Node*>& size_matcher,
const Matcher<Node*>& effect_matcher,
@@ -2197,6 +2250,7 @@
IS_BINOP_MATCHER(NumberShiftRight)
IS_BINOP_MATCHER(NumberShiftRightLogical)
IS_BINOP_MATCHER(NumberImul)
+IS_BINOP_MATCHER(NumberAtan2)
IS_BINOP_MATCHER(Word32And)
IS_BINOP_MATCHER(Word32Or)
IS_BINOP_MATCHER(Word32Xor)
@@ -2256,10 +2310,32 @@
IS_UNOP_MATCHER(Float64RoundTiesAway)
IS_UNOP_MATCHER(Float64ExtractLowWord32)
IS_UNOP_MATCHER(Float64ExtractHighWord32)
+IS_UNOP_MATCHER(NumberAbs)
+IS_UNOP_MATCHER(NumberAtan)
+IS_UNOP_MATCHER(NumberAtanh)
+IS_UNOP_MATCHER(NumberCeil)
+IS_UNOP_MATCHER(NumberClz32)
+IS_UNOP_MATCHER(NumberCbrt)
+IS_UNOP_MATCHER(NumberCos)
+IS_UNOP_MATCHER(NumberExp)
+IS_UNOP_MATCHER(NumberExpm1)
+IS_UNOP_MATCHER(NumberFloor)
+IS_UNOP_MATCHER(NumberFround)
+IS_UNOP_MATCHER(NumberLog)
+IS_UNOP_MATCHER(NumberLog1p)
+IS_UNOP_MATCHER(NumberLog10)
+IS_UNOP_MATCHER(NumberLog2)
+IS_UNOP_MATCHER(NumberRound)
+IS_UNOP_MATCHER(NumberSin)
+IS_UNOP_MATCHER(NumberSqrt)
+IS_UNOP_MATCHER(NumberTan)
+IS_UNOP_MATCHER(NumberTrunc)
IS_UNOP_MATCHER(NumberToInt32)
IS_UNOP_MATCHER(NumberToUint32)
+IS_UNOP_MATCHER(PlainPrimitiveToNumber)
IS_UNOP_MATCHER(ObjectIsReceiver)
IS_UNOP_MATCHER(ObjectIsSmi)
+IS_UNOP_MATCHER(StringFromCharCode)
IS_UNOP_MATCHER(Word32Clz)
IS_UNOP_MATCHER(Word32Ctz)
IS_UNOP_MATCHER(Word32Popcnt)
diff --git a/test/unittests/compiler/node-test-utils.h b/test/unittests/compiler/node-test-utils.h
index 4979bd5..60a0895 100644
--- a/test/unittests/compiler/node-test-utils.h
+++ b/test/unittests/compiler/node-test-utils.h
@@ -6,6 +6,7 @@
#define V8_UNITTESTS_COMPILER_NODE_TEST_UTILS_H_
#include "src/compiler/machine-operator.h"
+#include "src/compiler/type-hints.h"
#include "src/machine-type.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -199,6 +200,18 @@
const Matcher<Node*>& rhs_matcher);
Matcher<Node*> IsNumberLessThan(const Matcher<Node*>& lhs_matcher,
const Matcher<Node*>& rhs_matcher);
+Matcher<Node*> IsNumberAdd(const Matcher<Node*>& lhs_matcher,
+ const Matcher<Node*>& rhs_matcher);
+Matcher<Node*> IsSpeculativeNumberAdd(
+ const Matcher<BinaryOperationHints::Hint>& hint_matcher,
+ const Matcher<Node*>& lhs_matcher, const Matcher<Node*>& rhs_matcher,
+ const Matcher<Node*>& effect_matcher,
+ const Matcher<Node*>& control_matcher);
+Matcher<Node*> IsSpeculativeNumberSubtract(
+ const Matcher<BinaryOperationHints::Hint>& hint_matcher,
+ const Matcher<Node*>& lhs_matcher, const Matcher<Node*>& rhs_matcher,
+ const Matcher<Node*>& effect_matcher,
+ const Matcher<Node*>& control_matcher);
Matcher<Node*> IsNumberSubtract(const Matcher<Node*>& lhs_matcher,
const Matcher<Node*>& rhs_matcher);
Matcher<Node*> IsNumberMultiply(const Matcher<Node*>& lhs_matcher,
@@ -211,6 +224,29 @@
const Matcher<Node*>& rhs_matcher);
Matcher<Node*> IsNumberImul(const Matcher<Node*>& lhs_matcher,
const Matcher<Node*>& rhs_matcher);
+Matcher<Node*> IsNumberAbs(const Matcher<Node*>& value_matcher);
+Matcher<Node*> IsNumberAtan(const Matcher<Node*>& value_matcher);
+Matcher<Node*> IsNumberAtan2(const Matcher<Node*>& lhs_matcher,
+ const Matcher<Node*>& rhs_matcher);
+Matcher<Node*> IsNumberAtanh(const Matcher<Node*>& value_matcher);
+Matcher<Node*> IsNumberCeil(const Matcher<Node*>& value_matcher);
+Matcher<Node*> IsNumberClz32(const Matcher<Node*>& value_matcher);
+Matcher<Node*> IsNumberCos(const Matcher<Node*>& value_matcher);
+Matcher<Node*> IsNumberExp(const Matcher<Node*>& value_matcher);
+Matcher<Node*> IsNumberExpm1(const Matcher<Node*>& value_matcher);
+Matcher<Node*> IsNumberFloor(const Matcher<Node*>& value_matcher);
+Matcher<Node*> IsNumberFround(const Matcher<Node*>& value_matcher);
+Matcher<Node*> IsNumberLog(const Matcher<Node*>& value_matcher);
+Matcher<Node*> IsNumberLog1p(const Matcher<Node*>& value_matcher);
+Matcher<Node*> IsNumberLog2(const Matcher<Node*>& value_matcher);
+Matcher<Node*> IsNumberLog10(const Matcher<Node*>& value_matcher);
+Matcher<Node*> IsNumberRound(const Matcher<Node*>& value_matcher);
+Matcher<Node*> IsNumberCbrt(const Matcher<Node*>& value_matcher);
+Matcher<Node*> IsNumberSin(const Matcher<Node*>& value_matcher);
+Matcher<Node*> IsNumberSqrt(const Matcher<Node*>& value_matcher);
+Matcher<Node*> IsNumberTan(const Matcher<Node*>& value_matcher);
+Matcher<Node*> IsNumberTrunc(const Matcher<Node*>& value_matcher);
+Matcher<Node*> IsStringFromCharCode(const Matcher<Node*>& value_matcher);
Matcher<Node*> IsAllocate(const Matcher<Node*>& size_matcher,
const Matcher<Node*>& effect_matcher,
const Matcher<Node*>& control_matcher);
@@ -361,6 +397,7 @@
Matcher<Node*> IsParameter(const Matcher<int> index_matcher);
Matcher<Node*> IsLoadFramePointer();
Matcher<Node*> IsLoadParentFramePointer();
+Matcher<Node*> IsPlainPrimitiveToNumber(const Matcher<Node*>& input_matcher);
Matcher<Node*> IsInt32PairAdd(const Matcher<Node*>& a_matcher,
const Matcher<Node*>& b_matcher,
diff --git a/test/unittests/compiler/register-allocator-unittest.cc b/test/unittests/compiler/register-allocator-unittest.cc
index c5ff90f..71a726f 100644
--- a/test/unittests/compiler/register-allocator-unittest.cc
+++ b/test/unittests/compiler/register-allocator-unittest.cc
@@ -678,8 +678,7 @@
Allocate();
// TODO(mtrofin): at the moment, the linear allocator spills var1 and var2,
- // so only var3 is spilled in deferred blocks. Greedy avoids spilling 1&2.
- // Expand the test once greedy is back online with this facility.
+ // so only var3 is spilled in deferred blocks.
const int var3_reg = 2;
const int var3_slot = 2;
diff --git a/test/unittests/compiler/simplified-operator-reducer-unittest.cc b/test/unittests/compiler/simplified-operator-reducer-unittest.cc
index eec39ab..f84b9bf 100644
--- a/test/unittests/compiler/simplified-operator-reducer-unittest.cc
+++ b/test/unittests/compiler/simplified-operator-reducer-unittest.cc
@@ -32,7 +32,8 @@
JSOperatorBuilder javascript(zone());
JSGraph jsgraph(isolate(), graph(), common(), &javascript, simplified(),
&machine);
- SimplifiedOperatorReducer reducer(&jsgraph);
+ GraphReducer graph_reducer(zone(), graph());
+ SimplifiedOperatorReducer reducer(&graph_reducer, &jsgraph);
return reducer.Reduce(node);
}
@@ -91,26 +92,6 @@
1866841746, 2032089723, 2147483647};
-const uint32_t kUint32Values[] = {
- 0x0, 0x5, 0x8, 0xc, 0xd, 0x26,
- 0x28, 0x29, 0x30, 0x34, 0x3e, 0x42,
- 0x50, 0x5b, 0x63, 0x71, 0x77, 0x7c,
- 0x83, 0x88, 0x96, 0x9c, 0xa3, 0xfa,
- 0x7a7, 0x165d, 0x234d, 0x3acb, 0x43a5, 0x4573,
- 0x5b4f, 0x5f14, 0x6996, 0x6c6e, 0x7289, 0x7b9a,
- 0x7bc9, 0x86bb, 0xa839, 0xaa41, 0xb03b, 0xc942,
- 0xce68, 0xcf4c, 0xd3ad, 0xdea3, 0xe90c, 0xed86,
- 0xfba5, 0x172dcc6, 0x114d8fc1, 0x182d6c9d, 0x1b1e3fad, 0x1db033bf,
- 0x1e1de755, 0x1f625c80, 0x28f6cf00, 0x2acb6a94, 0x2c20240e, 0x2f0fe54e,
- 0x31863a7c, 0x33325474, 0x3532fae3, 0x3bab82ea, 0x4c4b83a2, 0x4cd93d1e,
- 0x4f7331d4, 0x5491b09b, 0x57cc6ff9, 0x60d3b4dc, 0x653f5904, 0x690ae256,
- 0x69fe3276, 0x6bebf0ba, 0x6e2c69a3, 0x73b84ff7, 0x7b3a1924, 0x7ed032d9,
- 0x84dd734b, 0x8552ea53, 0x8680754f, 0x8e9660eb, 0x94fe2b9c, 0x972d30cf,
- 0x9b98c482, 0xb158667e, 0xb432932c, 0xb5b70989, 0xb669971a, 0xb7c359d1,
- 0xbeb15c0d, 0xc171c53d, 0xc743dd38, 0xc8e2af50, 0xc98e2df0, 0xd9d1cdf9,
- 0xdcc91049, 0xe46f396d, 0xee991950, 0xef64e521, 0xf7aeefc9, 0xffffffff};
-
-
const double kNaNs[] = {-std::numeric_limits<double>::quiet_NaN(),
std::numeric_limits<double>::quiet_NaN(),
bit_cast<double>(V8_UINT64_C(0x7FFFFFFFFFFFFFFF)),
@@ -314,26 +295,6 @@
}
-TEST_F(SimplifiedOperatorReducerTest, ChangeTaggedToInt32WithConstant) {
- TRACED_FOREACH(double, n, kFloat64Values) {
- Reduction reduction = Reduce(graph()->NewNode(
- simplified()->ChangeTaggedToInt32(), NumberConstant(n)));
- ASSERT_TRUE(reduction.Changed());
- EXPECT_THAT(reduction.replacement(), IsInt32Constant(DoubleToInt32(n)));
- }
-}
-
-
-TEST_F(SimplifiedOperatorReducerTest, ChangeTaggedToInt32WithNaNConstant) {
- TRACED_FOREACH(double, nan, kNaNs) {
- Reduction reduction = Reduce(graph()->NewNode(
- simplified()->ChangeTaggedToInt32(), NumberConstant(nan)));
- ASSERT_TRUE(reduction.Changed());
- EXPECT_THAT(reduction.replacement(), IsInt32Constant(0));
- }
-}
-
-
// -----------------------------------------------------------------------------
// ChangeTaggedToUint32
@@ -360,41 +321,6 @@
}
-TEST_F(SimplifiedOperatorReducerTest, ChangeTaggedToUint32WithConstant) {
- TRACED_FOREACH(double, n, kFloat64Values) {
- Reduction reduction = Reduce(graph()->NewNode(
- simplified()->ChangeTaggedToUint32(), NumberConstant(n)));
- ASSERT_TRUE(reduction.Changed());
- EXPECT_THAT(reduction.replacement(),
- IsInt32Constant(bit_cast<int32_t>(DoubleToUint32(n))));
- }
-}
-
-
-TEST_F(SimplifiedOperatorReducerTest, ChangeTaggedToUint32WithNaNConstant) {
- TRACED_FOREACH(double, nan, kNaNs) {
- Reduction reduction = Reduce(graph()->NewNode(
- simplified()->ChangeTaggedToUint32(), NumberConstant(nan)));
- ASSERT_TRUE(reduction.Changed());
- EXPECT_THAT(reduction.replacement(), IsInt32Constant(0));
- }
-}
-
-
-// -----------------------------------------------------------------------------
-// ChangeUint32ToTagged
-
-
-TEST_F(SimplifiedOperatorReducerTest, ChangeUint32ToTagged) {
- TRACED_FOREACH(uint32_t, n, kUint32Values) {
- Reduction reduction =
- Reduce(graph()->NewNode(simplified()->ChangeUint32ToTagged(),
- Int32Constant(bit_cast<int32_t>(n))));
- ASSERT_TRUE(reduction.Changed());
- EXPECT_THAT(reduction.replacement(), IsNumberConstant(BitEq(FastUI2D(n))));
- }
-}
-
// -----------------------------------------------------------------------------
// TruncateTaggedToWord32
@@ -417,6 +343,116 @@
}
}
+// -----------------------------------------------------------------------------
+// CheckTaggedPointer
+
+TEST_F(SimplifiedOperatorReducerTest, CheckTaggedPointerWithChangeBitToTagged) {
+ Node* param0 = Parameter(0);
+ Node* effect = graph()->start();
+ Node* control = graph()->start();
+ Node* value = graph()->NewNode(simplified()->ChangeBitToTagged(), param0);
+ Reduction reduction = Reduce(graph()->NewNode(
+ simplified()->CheckTaggedPointer(), value, effect, control));
+ ASSERT_TRUE(reduction.Changed());
+ EXPECT_EQ(value, reduction.replacement());
+}
+
+TEST_F(SimplifiedOperatorReducerTest, CheckTaggedPointerWithHeapConstant) {
+ Node* effect = graph()->start();
+ Node* control = graph()->start();
+ Handle<HeapObject> kHeapObjects[] = {
+ factory()->empty_string(), factory()->null_value(),
+ factory()->species_symbol(), factory()->undefined_value()};
+ TRACED_FOREACH(Handle<HeapObject>, object, kHeapObjects) {
+ Node* value = HeapConstant(object);
+ Reduction reduction = Reduce(graph()->NewNode(
+ simplified()->CheckTaggedPointer(), value, effect, control));
+ ASSERT_TRUE(reduction.Changed());
+ EXPECT_EQ(value, reduction.replacement());
+ }
+}
+
+// -----------------------------------------------------------------------------
+// CheckTaggedSigned
+
+TEST_F(SimplifiedOperatorReducerTest,
+ CheckTaggedSignedWithChangeInt31ToTaggedSigned) {
+ Node* param0 = Parameter(0);
+ Node* effect = graph()->start();
+ Node* control = graph()->start();
+ Node* value =
+ graph()->NewNode(simplified()->ChangeInt31ToTaggedSigned(), param0);
+ Reduction reduction = Reduce(graph()->NewNode(
+ simplified()->CheckTaggedSigned(), value, effect, control));
+ ASSERT_TRUE(reduction.Changed());
+ EXPECT_EQ(value, reduction.replacement());
+}
+
+TEST_F(SimplifiedOperatorReducerTest, CheckTaggedSignedWithNumberConstant) {
+ Node* effect = graph()->start();
+ Node* control = graph()->start();
+ Node* value = NumberConstant(1.0);
+ Reduction reduction = Reduce(graph()->NewNode(
+ simplified()->CheckTaggedSigned(), value, effect, control));
+ ASSERT_TRUE(reduction.Changed());
+ EXPECT_EQ(value, reduction.replacement());
+}
+
+// -----------------------------------------------------------------------------
+// NumberAbs
+
+TEST_F(SimplifiedOperatorReducerTest, NumberAbsWithNumberConstant) {
+ TRACED_FOREACH(double, n, kFloat64Values) {
+ Reduction reduction =
+ Reduce(graph()->NewNode(simplified()->NumberAbs(), NumberConstant(n)));
+ ASSERT_TRUE(reduction.Changed());
+ EXPECT_THAT(reduction.replacement(), IsNumberConstant(std::fabs(n)));
+ }
+}
+
+// -----------------------------------------------------------------------------
+// ObjectIsSmi
+
+TEST_F(SimplifiedOperatorReducerTest, ObjectIsSmiWithChangeBitToTagged) {
+ Node* param0 = Parameter(0);
+ Reduction reduction = Reduce(graph()->NewNode(
+ simplified()->ObjectIsSmi(),
+ graph()->NewNode(simplified()->ChangeBitToTagged(), param0)));
+ ASSERT_TRUE(reduction.Changed());
+ EXPECT_THAT(reduction.replacement(), IsFalseConstant());
+}
+
+TEST_F(SimplifiedOperatorReducerTest,
+ ObjectIsSmiWithChangeInt31ToTaggedSigned) {
+ Node* param0 = Parameter(0);
+ Reduction reduction = Reduce(graph()->NewNode(
+ simplified()->ObjectIsSmi(),
+ graph()->NewNode(simplified()->ChangeInt31ToTaggedSigned(), param0)));
+ ASSERT_TRUE(reduction.Changed());
+ EXPECT_THAT(reduction.replacement(), IsTrueConstant());
+}
+
+TEST_F(SimplifiedOperatorReducerTest, ObjectIsSmiWithHeapConstant) {
+ Handle<HeapObject> kHeapObjects[] = {
+ factory()->empty_string(), factory()->null_value(),
+ factory()->species_symbol(), factory()->undefined_value()};
+ TRACED_FOREACH(Handle<HeapObject>, o, kHeapObjects) {
+ Reduction reduction =
+ Reduce(graph()->NewNode(simplified()->ObjectIsSmi(), HeapConstant(o)));
+ ASSERT_TRUE(reduction.Changed());
+ EXPECT_THAT(reduction.replacement(), IsFalseConstant());
+ }
+}
+
+TEST_F(SimplifiedOperatorReducerTest, ObjectIsSmiWithNumberConstant) {
+ TRACED_FOREACH(double, n, kFloat64Values) {
+ Reduction reduction = Reduce(
+ graph()->NewNode(simplified()->ObjectIsSmi(), NumberConstant(n)));
+ ASSERT_TRUE(reduction.Changed());
+ EXPECT_THAT(reduction.replacement(), IsBooleanConstant(IsSmiDouble(n)));
+ }
+}
+
} // namespace compiler
} // namespace internal
} // namespace v8
diff --git a/test/unittests/compiler/simplified-operator-unittest.cc b/test/unittests/compiler/simplified-operator-unittest.cc
index ba404a9..3343c8f 100644
--- a/test/unittests/compiler/simplified-operator-unittest.cc
+++ b/test/unittests/compiler/simplified-operator-unittest.cc
@@ -156,7 +156,8 @@
const Operator* op = simplified.LoadBuffer(access);
EXPECT_EQ(IrOpcode::kLoadBuffer, op->opcode());
- EXPECT_EQ(Operator::kNoThrow | Operator::kNoWrite, op->properties());
+ EXPECT_EQ(Operator::kNoDeopt | Operator::kNoThrow | Operator::kNoWrite,
+ op->properties());
EXPECT_EQ(access, BufferAccessOf(op));
EXPECT_EQ(3, op->ValueInputCount());
@@ -176,7 +177,8 @@
const Operator* op = simplified.StoreBuffer(access);
EXPECT_EQ(IrOpcode::kStoreBuffer, op->opcode());
- EXPECT_EQ(Operator::kNoRead | Operator::kNoThrow, op->properties());
+ EXPECT_EQ(Operator::kNoDeopt | Operator::kNoRead | Operator::kNoThrow,
+ op->properties());
EXPECT_EQ(access, BufferAccessOf(op));
EXPECT_EQ(4, op->ValueInputCount());
@@ -258,7 +260,8 @@
const Operator* op = simplified.LoadElement(access);
EXPECT_EQ(IrOpcode::kLoadElement, op->opcode());
- EXPECT_EQ(Operator::kNoThrow | Operator::kNoWrite, op->properties());
+ EXPECT_EQ(Operator::kNoDeopt | Operator::kNoThrow | Operator::kNoWrite,
+ op->properties());
EXPECT_EQ(access, ElementAccessOf(op));
EXPECT_EQ(2, op->ValueInputCount());
@@ -278,7 +281,8 @@
const Operator* op = simplified.StoreElement(access);
EXPECT_EQ(IrOpcode::kStoreElement, op->opcode());
- EXPECT_EQ(Operator::kNoRead | Operator::kNoThrow, op->properties());
+ EXPECT_EQ(Operator::kNoDeopt | Operator::kNoRead | Operator::kNoThrow,
+ op->properties());
EXPECT_EQ(access, ElementAccessOf(op));
EXPECT_EQ(3, op->ValueInputCount());
diff --git a/test/unittests/compiler/typer-unittest.cc b/test/unittests/compiler/typer-unittest.cc
index 9d664a6..61e00a5 100644
--- a/test/unittests/compiler/typer-unittest.cc
+++ b/test/unittests/compiler/typer-unittest.cc
@@ -290,44 +290,51 @@
TEST_F(TyperTest, TypeJSLessThan) {
- TestBinaryCompareOp(javascript_.LessThan(), std::less<double>());
+ TestBinaryCompareOp(javascript_.LessThan(CompareOperationHints::Any()),
+ std::less<double>());
}
TEST_F(TyperTest, TypeJSLessThanOrEqual) {
- TestBinaryCompareOp(javascript_.LessThanOrEqual(), std::less_equal<double>());
+ TestBinaryCompareOp(javascript_.LessThanOrEqual(CompareOperationHints::Any()),
+ std::less_equal<double>());
}
TEST_F(TyperTest, TypeJSGreaterThan) {
- TestBinaryCompareOp(javascript_.GreaterThan(), std::greater<double>());
+ TestBinaryCompareOp(javascript_.GreaterThan(CompareOperationHints::Any()),
+ std::greater<double>());
}
TEST_F(TyperTest, TypeJSGreaterThanOrEqual) {
- TestBinaryCompareOp(javascript_.GreaterThanOrEqual(),
- std::greater_equal<double>());
+ TestBinaryCompareOp(
+ javascript_.GreaterThanOrEqual(CompareOperationHints::Any()),
+ std::greater_equal<double>());
}
TEST_F(TyperTest, TypeJSEqual) {
- TestBinaryCompareOp(javascript_.Equal(), std::equal_to<double>());
+ TestBinaryCompareOp(javascript_.Equal(CompareOperationHints::Any()),
+ std::equal_to<double>());
}
TEST_F(TyperTest, TypeJSNotEqual) {
- TestBinaryCompareOp(javascript_.NotEqual(), std::not_equal_to<double>());
+ TestBinaryCompareOp(javascript_.NotEqual(CompareOperationHints::Any()),
+ std::not_equal_to<double>());
}
// For numbers there's no difference between strict and non-strict equality.
TEST_F(TyperTest, TypeJSStrictEqual) {
- TestBinaryCompareOp(javascript_.StrictEqual(), std::equal_to<double>());
+ TestBinaryCompareOp(javascript_.StrictEqual(CompareOperationHints::Any()),
+ std::equal_to<double>());
}
TEST_F(TyperTest, TypeJSStrictNotEqual) {
- TestBinaryCompareOp(javascript_.StrictNotEqual(),
+ TestBinaryCompareOp(javascript_.StrictNotEqual(CompareOperationHints::Any()),
std::not_equal_to<double>());
}
@@ -335,10 +342,9 @@
//------------------------------------------------------------------------------
// Monotonicity
-
-#define TEST_BINARY_MONOTONICITY(name) \
- TEST_F(TyperTest, Monotonicity_##name) { \
- TestBinaryMonotonicity(javascript_.name()); \
+#define TEST_BINARY_MONOTONICITY(name) \
+ TEST_F(TyperTest, Monotonicity_##name) { \
+ TestBinaryMonotonicity(javascript_.name(CompareOperationHints::Any())); \
}
TEST_BINARY_MONOTONICITY(Equal)
TEST_BINARY_MONOTONICITY(NotEqual)