Revision: 24942
Author: [email protected]
Date: Tue Oct 28 13:56:26 2014 UTC
Log: [turbofan] Complete support for integer division/modulus in
simplified lowering.
Also add backend flags that tell whether integer division/modulus is
generally safe, i.e. does not trap on overflow or divide by zero.
TEST=unittests
[email protected]
Review URL: https://codereview.chromium.org/681133004
https://code.google.com/p/v8/source/detail?r=24942
Modified:
/branches/bleeding_edge/src/compiler/arm/instruction-selector-arm.cc
/branches/bleeding_edge/src/compiler/arm64/instruction-selector-arm64.cc
/branches/bleeding_edge/src/compiler/ia32/instruction-selector-ia32.cc
/branches/bleeding_edge/src/compiler/machine-operator-reducer.cc
/branches/bleeding_edge/src/compiler/machine-operator.h
/branches/bleeding_edge/src/compiler/node-matchers.h
/branches/bleeding_edge/src/compiler/operator-properties-inl.h
/branches/bleeding_edge/src/compiler/simplified-lowering.cc
/branches/bleeding_edge/src/compiler/simplified-lowering.h
/branches/bleeding_edge/src/compiler/x64/instruction-selector-x64.cc
/branches/bleeding_edge/test/cctest/compiler/test-simplified-lowering.cc
/branches/bleeding_edge/test/unittests/compiler/machine-operator-unittest.cc
=======================================
--- /branches/bleeding_edge/src/compiler/arm/instruction-selector-arm.cc
Fri Oct 24 13:06:48 2014 UTC
+++ /branches/bleeding_edge/src/compiler/arm/instruction-selector-arm.cc
Tue Oct 28 13:56:26 2014 UTC
@@ -1139,8 +1139,12 @@
// static
MachineOperatorBuilder::Flags
InstructionSelector::SupportedMachineOperatorFlags() {
- return MachineOperatorBuilder::Flag::kNoFlags;
+ return MachineOperatorBuilder::kInt32DivIsSafe |
+ MachineOperatorBuilder::kInt32ModIsSafe |
+ MachineOperatorBuilder::kUint32DivIsSafe |
+ MachineOperatorBuilder::kUint32ModIsSafe;
}
+
} // namespace compiler
} // namespace internal
} // namespace v8
=======================================
---
/branches/bleeding_edge/src/compiler/arm64/instruction-selector-arm64.cc
Fri Oct 24 15:29:19 2014 UTC
+++
/branches/bleeding_edge/src/compiler/arm64/instruction-selector-arm64.cc
Tue Oct 28 13:56:26 2014 UTC
@@ -1300,8 +1300,9 @@
// static
MachineOperatorBuilder::Flags
InstructionSelector::SupportedMachineOperatorFlags() {
- return MachineOperatorBuilder::Flag::kNoFlags;
+ return MachineOperatorBuilder::kNoFlags;
}
+
} // namespace compiler
} // namespace internal
} // namespace v8
=======================================
--- /branches/bleeding_edge/src/compiler/ia32/instruction-selector-ia32.cc
Fri Oct 24 13:06:48 2014 UTC
+++ /branches/bleeding_edge/src/compiler/ia32/instruction-selector-ia32.cc
Tue Oct 28 13:56:26 2014 UTC
@@ -881,8 +881,9 @@
// static
MachineOperatorBuilder::Flags
InstructionSelector::SupportedMachineOperatorFlags() {
- return MachineOperatorBuilder::Flag::kNoFlags;
+ return MachineOperatorBuilder::kNoFlags;
}
+
} // namespace compiler
} // namespace internal
} // namespace v8
=======================================
--- /branches/bleeding_edge/src/compiler/machine-operator-reducer.cc Tue
Oct 28 11:57:20 2014 UTC
+++ /branches/bleeding_edge/src/compiler/machine-operator-reducer.cc Tue
Oct 28 13:56:26 2014 UTC
@@ -555,6 +555,7 @@
node->set_op(machine()->Int32Sub());
node->ReplaceInput(0, Int32Constant(0));
node->ReplaceInput(1, m.left().node());
+ node->TrimInputCount(2);
return Changed(node);
}
if (m.right().HasValue()) {
@@ -576,6 +577,7 @@
node->set_op(machine()->Int32Sub());
node->ReplaceInput(0, Int32Constant(0));
node->ReplaceInput(1, quotient);
+ node->TrimInputCount(2);
return Changed(node);
}
return Replace(quotient);
@@ -644,6 +646,7 @@
node->set_op(machine()->Int32Sub());
DCHECK_EQ(dividend, node->InputAt(0));
node->ReplaceInput(1, Int32Mul(quotient, Int32Constant(divisor)));
+ node->TrimInputCount(2);
return Changed(node);
}
}
=======================================
--- /branches/bleeding_edge/src/compiler/machine-operator.h Mon Oct 27
09:36:51 2014 UTC
+++ /branches/bleeding_edge/src/compiler/machine-operator.h Tue Oct 28
13:56:26 2014 UTC
@@ -60,17 +60,21 @@
public:
// Flags that specify which operations are available. This is useful
// for operations that are unsupported by some back-ends.
- enum class Flag : unsigned {
- kNoFlags = 0,
- kFloat64Floor = 1 << 0,
- kFloat64Ceil = 1 << 1,
- kFloat64RoundTruncate = 1 << 2,
- kFloat64RoundTiesAway = 1 << 3
+ enum Flag {
+ kNoFlags = 0u,
+ kFloat64Floor = 1u << 0,
+ kFloat64Ceil = 1u << 1,
+ kFloat64RoundTruncate = 1u << 2,
+ kFloat64RoundTiesAway = 1u << 3,
+ kInt32DivIsSafe = 1u << 4,
+ kInt32ModIsSafe = 1u << 5,
+ kUint32DivIsSafe = 1u << 6,
+ kUint32ModIsSafe = 1u << 7
};
typedef base::Flags<Flag, unsigned> Flags;
explicit MachineOperatorBuilder(MachineType word = kMachPtr,
- Flags supportedOperators =
Flag::kNoFlags);
+ Flags supportedOperators = kNoFlags);
const Operator* Word32And();
const Operator* Word32Or();
@@ -104,6 +108,10 @@
const Operator* Uint32LessThan();
const Operator* Uint32LessThanOrEqual();
const Operator* Uint32Mod();
+ bool Int32DivIsSafe() const { return flags_ & kInt32DivIsSafe; }
+ bool Int32ModIsSafe() const { return flags_ & kInt32ModIsSafe; }
+ bool Uint32DivIsSafe() const { return flags_ & kUint32DivIsSafe; }
+ bool Uint32ModIsSafe() const { return flags_ & kUint32ModIsSafe; }
const Operator* Int64Add();
const Operator* Int64Sub();
@@ -153,14 +161,10 @@
const Operator* Float64Ceil();
const Operator* Float64RoundTruncate();
const Operator* Float64RoundTiesAway();
- bool HasFloat64Floor() { return flags_ & Flag::kFloat64Floor; }
- bool HasFloat64Ceil() { return flags_ & Flag::kFloat64Ceil; }
- bool HasFloat64RoundTruncate() {
- return flags_ & Flag::kFloat64RoundTruncate;
- }
- bool HasFloat64RoundTiesAway() {
- return flags_ & Flag::kFloat64RoundTiesAway;
- }
+ bool HasFloat64Floor() { return flags_ & kFloat64Floor; }
+ bool HasFloat64Ceil() { return flags_ & kFloat64Ceil; }
+ bool HasFloat64RoundTruncate() { return flags_ & kFloat64RoundTruncate; }
+ bool HasFloat64RoundTiesAway() { return flags_ & kFloat64RoundTiesAway; }
// load [base + index]
const Operator* Load(LoadRepresentation rep);
=======================================
--- /branches/bleeding_edge/src/compiler/node-matchers.h Tue Oct 28
08:28:36 2014 UTC
+++ /branches/bleeding_edge/src/compiler/node-matchers.h Tue Oct 28
13:56:26 2014 UTC
@@ -139,6 +139,7 @@
typedef BinopMatcher<Int64Matcher, Int64Matcher> Int64BinopMatcher;
typedef BinopMatcher<Uint64Matcher, Uint64Matcher> Uint64BinopMatcher;
typedef BinopMatcher<Float64Matcher, Float64Matcher> Float64BinopMatcher;
+typedef BinopMatcher<NumberMatcher, NumberMatcher> NumberBinopMatcher;
// Fairly intel-specify node matcher used for matching scale factors in
=======================================
--- /branches/bleeding_edge/src/compiler/operator-properties-inl.h Tue Oct
28 13:00:11 2014 UTC
+++ /branches/bleeding_edge/src/compiler/operator-properties-inl.h Tue Oct
28 13:56:26 2014 UTC
@@ -123,6 +123,10 @@
case IrOpcode::kEffectPhi:
case IrOpcode::kLoad:
case IrOpcode::kLoadField:
+ case IrOpcode::kInt32Div:
+ case IrOpcode::kInt32Mod:
+ case IrOpcode::kUint32Div:
+ case IrOpcode::kUint32Mod:
return 1;
#define OPCODE_CASE(x) case IrOpcode::k##x:
CONTROL_OP_LIST(OPCODE_CASE)
=======================================
--- /branches/bleeding_edge/src/compiler/simplified-lowering.cc Tue Oct 28
13:00:11 2014 UTC
+++ /branches/bleeding_edge/src/compiler/simplified-lowering.cc Tue Oct 28
13:56:26 2014 UTC
@@ -605,19 +605,17 @@
break;
}
case IrOpcode::kNumberDivide: {
- NumberMatcher right(node->InputAt(1));
- if (right.HasValue() && !right.Is(0) && !right.Is(-1)) {
- if (CanLowerToInt32Binop(node, use)) {
- // => signed Int32Div
- VisitInt32Binop(node);
- if (lower()) node->set_op(Int32Op(node));
- break;
- } else if (CanLowerToUint32Binop(node, use)) {
- // => unsigned Uint32Div
- VisitUint32Binop(node);
- if (lower()) node->set_op(Uint32Op(node));
- break;
- }
+ if (CanLowerToInt32Binop(node, use)) {
+ // => signed Int32Div
+ VisitInt32Binop(node);
+ if (lower()) DeferReplacement(node, lowering->Int32Div(node));
+ break;
+ }
+ if (CanLowerToUint32Binop(node, use)) {
+ // => unsigned Uint32Div
+ VisitUint32Binop(node);
+ if (lower()) DeferReplacement(node, lowering->Uint32Div(node));
+ break;
}
// => Float64Div
VisitFloat64Binop(node);
@@ -625,20 +623,17 @@
break;
}
case IrOpcode::kNumberModulus: {
- NumberMatcher right(node->InputAt(1));
- if (right.HasValue() && !right.Is(0) && !right.Is(-1)) {
- if (BothInputsAre(node, Type::Signed32()) &&
- !CanObserveMinusZero(use)) {
- // => signed Int32Mod
- VisitInt32Binop(node);
- if (lower()) node->set_op(Int32Op(node));
- break;
- } else if (BothInputsAre(node, Type::Unsigned32())) {
- // => unsigned Uint32Mod
- VisitUint32Binop(node);
- if (lower()) node->set_op(Uint32Op(node));
- break;
- }
+ if (CanLowerToInt32Binop(node, use)) {
+ // => signed Int32Mod
+ VisitInt32Binop(node);
+ if (lower()) DeferReplacement(node, lowering->Int32Mod(node));
+ break;
+ }
+ if (CanLowerToUint32Binop(node, use)) {
+ // => unsigned Uint32Mod
+ VisitUint32Binop(node);
+ if (lower()) DeferReplacement(node, lowering->Uint32Mod(node));
+ break;
}
// => Float64Mod
VisitFloat64Binop(node);
@@ -1216,6 +1211,148 @@
jsgraph()->Int32Constant(2),
jsgraph()->UndefinedConstant());
}
+
+
+Node* SimplifiedLowering::Int32Div(Node* const node) {
+ Int32BinopMatcher m(node);
+ Node* const zero = jsgraph()->Int32Constant(0);
+ Node* const lhs = m.left().node();
+ Node* const rhs = m.right().node();
+
+ if (m.right().Is(-1)) {
+ return graph()->NewNode(machine()->Int32Sub(), zero, lhs);
+ } else if (m.right().Is(0)) {
+ return rhs;
+ } else if (machine()->Int32DivIsSafe() || m.right().HasValue()) {
+ return graph()->NewNode(machine()->Int32Div(), lhs, rhs,
graph()->start());
+ }
+
+ Node* check0 = graph()->NewNode(machine()->Word32Equal(), rhs, zero);
+ Node* branch0 = graph()->NewNode(common()->Branch(BranchHint::kFalse),
check0,
+ graph()->start());
+
+ Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
+ Node* true0 = zero;
+
+ Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
+ Node* false0 = nullptr;
+ {
+ Node* check1 = graph()->NewNode(machine()->Word32Equal(), rhs,
+ jsgraph()->Int32Constant(-1));
+ Node* branch1 = graph()->NewNode(common()->Branch(BranchHint::kFalse),
+ check1, if_false0);
+
+ Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
+ Node* true1 = graph()->NewNode(machine()->Int32Sub(), zero, lhs);
+
+ Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
+ Node* false1 = graph()->NewNode(machine()->Int32Div(), lhs, rhs,
if_false1);
+
+ if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
+ false0 = graph()->NewNode(common()->Phi(kMachInt32, 2), true1, false1,
+ if_false0);
+ }
+
+ Node* merge0 = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
+ return graph()->NewNode(common()->Phi(kMachInt32, 2), true0, false0,
merge0);
+}
+
+
+Node* SimplifiedLowering::Int32Mod(Node* const node) {
+ Int32BinopMatcher m(node);
+ Node* const zero = jsgraph()->Int32Constant(0);
+ Node* const lhs = m.left().node();
+ Node* const rhs = m.right().node();
+
+ if (m.right().Is(-1) || m.right().Is(0)) {
+ return zero;
+ } else if (machine()->Int32ModIsSafe() || m.right().HasValue()) {
+ return graph()->NewNode(machine()->Int32Mod(), lhs, rhs,
graph()->start());
+ }
+
+ Node* check0 = graph()->NewNode(machine()->Word32Equal(), rhs, zero);
+ Node* branch0 = graph()->NewNode(common()->Branch(BranchHint::kFalse),
check0,
+ graph()->start());
+
+ Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
+ Node* true0 = zero;
+
+ Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
+ Node* false0 = nullptr;
+ {
+ Node* check1 = graph()->NewNode(machine()->Word32Equal(), rhs,
+ jsgraph()->Int32Constant(-1));
+ Node* branch1 = graph()->NewNode(common()->Branch(BranchHint::kFalse),
+ check1, if_false0);
+
+ Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
+ Node* true1 = zero;
+
+ Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
+ Node* false1 = graph()->NewNode(machine()->Int32Mod(), lhs, rhs,
if_false1);
+
+ if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
+ false0 = graph()->NewNode(common()->Phi(kMachInt32, 2), true1, false1,
+ if_false0);
+ }
+
+ Node* merge0 = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
+ return graph()->NewNode(common()->Phi(kMachInt32, 2), true0, false0,
merge0);
+}
+
+
+Node* SimplifiedLowering::Uint32Div(Node* const node) {
+ Uint32BinopMatcher m(node);
+ Node* const zero = jsgraph()->Uint32Constant(0);
+ Node* const lhs = m.left().node();
+ Node* const rhs = m.right().node();
+
+ if (m.right().Is(0)) {
+ return zero;
+ } else if (machine()->Uint32DivIsSafe() || m.right().HasValue()) {
+ return graph()->NewNode(machine()->Uint32Div(), lhs, rhs,
graph()->start());
+ }
+
+ Node* check = graph()->NewNode(machine()->Word32Equal(), rhs, zero);
+ Node* branch = graph()->NewNode(common()->Branch(BranchHint::kFalse),
check,
+ graph()->start());
+
+ Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
+ Node* vtrue = zero;
+
+ Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
+ Node* vfalse = graph()->NewNode(machine()->Uint32Div(), lhs, rhs,
if_false);
+
+ Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
+ return graph()->NewNode(common()->Phi(kMachUint32, 2), vtrue, vfalse,
merge);
+}
+
+
+Node* SimplifiedLowering::Uint32Mod(Node* const node) {
+ Uint32BinopMatcher m(node);
+ Node* const zero = jsgraph()->Uint32Constant(0);
+ Node* const lhs = m.left().node();
+ Node* const rhs = m.right().node();
+
+ if (m.right().Is(0)) {
+ return zero;
+ } else if (machine()->Uint32ModIsSafe() || m.right().HasValue()) {
+ return graph()->NewNode(machine()->Uint32Mod(), lhs, rhs,
graph()->start());
+ }
+
+ Node* check = graph()->NewNode(machine()->Word32Equal(), rhs, zero);
+ Node* branch = graph()->NewNode(common()->Branch(BranchHint::kFalse),
check,
+ graph()->start());
+
+ Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
+ Node* vtrue = zero;
+
+ Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
+ Node* vfalse = graph()->NewNode(machine()->Uint32Mod(), lhs, rhs,
if_false);
+
+ Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
+ return graph()->NewNode(common()->Phi(kMachUint32, 2), vtrue, vfalse,
merge);
+}
void SimplifiedLowering::DoStringEqual(Node* node) {
=======================================
--- /branches/bleeding_edge/src/compiler/simplified-lowering.h Wed Oct 8
11:16:45 2014 UTC
+++ /branches/bleeding_edge/src/compiler/simplified-lowering.h Tue Oct 28
13:56:26 2014 UTC
@@ -42,6 +42,10 @@
Node* OffsetMinusTagConstant(int32_t offset);
Node* ComputeIndex(const ElementAccess& access, Node* index);
Node* StringComparison(Node* node, bool requires_ordering);
+ Node* Int32Div(Node* const node);
+ Node* Int32Mod(Node* const node);
+ Node* Uint32Div(Node* const node);
+ Node* Uint32Mod(Node* const node);
friend class RepresentationSelector;
=======================================
--- /branches/bleeding_edge/src/compiler/x64/instruction-selector-x64.cc
Mon Oct 27 22:33:52 2014 UTC
+++ /branches/bleeding_edge/src/compiler/x64/instruction-selector-x64.cc
Tue Oct 28 13:56:26 2014 UTC
@@ -1112,8 +1112,9 @@
// static
MachineOperatorBuilder::Flags
InstructionSelector::SupportedMachineOperatorFlags() {
- return MachineOperatorBuilder::Flag::kNoFlags;
+ return MachineOperatorBuilder::kNoFlags;
}
+
} // namespace compiler
} // namespace internal
} // namespace v8
=======================================
---
/branches/bleeding_edge/test/cctest/compiler/test-simplified-lowering.cc
Mon Oct 27 22:33:52 2014 UTC
+++
/branches/bleeding_edge/test/cctest/compiler/test-simplified-lowering.cc
Tue Oct 28 13:56:26 2014 UTC
@@ -1720,11 +1720,11 @@
TestingGraph t(Type::Signed32());
Node* k = t.jsgraph.Constant(constants[i]);
Node* div = t.graph()->NewNode(t.simplified()->NumberDivide(), t.p0,
k);
- Node* trunc = t.graph()->NewNode(t.simplified()->NumberToInt32(), div);
- t.Return(trunc);
+ Node* use = t.Use(div, kMachInt32);
+ t.Return(use);
t.Lower();
- CHECK_EQ(IrOpcode::kInt32Div, div->opcode());
+ CHECK_EQ(IrOpcode::kInt32Div, use->InputAt(0)->opcode());
}
}
@@ -1761,11 +1761,11 @@
TestingGraph t(Type::Unsigned32());
Node* k = t.jsgraph.Constant(constants[i]);
Node* div = t.graph()->NewNode(t.simplified()->NumberDivide(), t.p0,
k);
- Node* trunc = t.graph()->NewNode(t.simplified()->NumberToUint32(),
div);
- t.Return(trunc);
+ Node* use = t.Use(div, kMachUint32);
+ t.Return(use);
t.Lower();
- CHECK_EQ(IrOpcode::kUint32Div, div->opcode());
+ CHECK_EQ(IrOpcode::kUint32Div, use->InputAt(0)->opcode());
}
}
@@ -1795,28 +1795,39 @@
TEST(NumberDivide_BadConstants) {
- int32_t constants[] = {-1, 0};
+ {
+ TestingGraph t(Type::Signed32());
+ Node* k = t.jsgraph.Constant(-1);
+ Node* div = t.graph()->NewNode(t.simplified()->NumberDivide(), t.p0,
k);
+ Node* use = t.Use(div, kMachInt32);
+ t.Return(use);
+ t.Lower();
- for (size_t i = 0; i < arraysize(constants); i++) {
+ CHECK_EQ(IrOpcode::kInt32Sub, use->InputAt(0)->opcode());
+ }
+
+ {
TestingGraph t(Type::Signed32());
- Node* k = t.jsgraph.Constant(constants[i]);
+ Node* k = t.jsgraph.Constant(0);
Node* div = t.graph()->NewNode(t.simplified()->NumberDivide(), t.p0,
k);
- Node* trunc = t.graph()->NewNode(t.simplified()->NumberToInt32(), div);
- t.Return(trunc);
+ Node* use = t.Use(div, kMachInt32);
+ t.Return(use);
t.Lower();
- CHECK_EQ(IrOpcode::kFloat64Div, div->opcode());
+ CHECK_EQ(IrOpcode::kInt32Constant, use->InputAt(0)->opcode());
+ CHECK_EQ(0, OpParameter<int32_t>(use->InputAt(0)));
}
{
TestingGraph t(Type::Unsigned32());
Node* k = t.jsgraph.Constant(0);
Node* div = t.graph()->NewNode(t.simplified()->NumberDivide(), t.p0,
k);
- Node* trunc = t.graph()->NewNode(t.simplified()->NumberToUint32(),
div);
- t.Return(trunc);
+ Node* use = t.Use(div, kMachUint32);
+ t.Return(use);
t.Lower();
- CHECK_EQ(IrOpcode::kFloat64Div, div->opcode());
+ CHECK_EQ(IrOpcode::kInt32Constant, use->InputAt(0)->opcode());
+ CHECK_EQ(0, OpParameter<int32_t>(use->InputAt(0)));
}
}
@@ -1828,11 +1839,11 @@
TestingGraph t(Type::Signed32());
Node* k = t.jsgraph.Constant(constants[i]);
Node* mod = t.graph()->NewNode(t.simplified()->NumberModulus(), t.p0,
k);
- Node* trunc = t.graph()->NewNode(t.simplified()->NumberToInt32(), mod);
- t.Return(trunc);
+ Node* use = t.Use(mod, kMachInt32);
+ t.Return(use);
t.Lower();
- CHECK_EQ(IrOpcode::kInt32Mod, mod->opcode());
+ CHECK_EQ(IrOpcode::kInt32Mod, use->InputAt(0)->opcode());
}
}
@@ -1870,10 +1881,10 @@
Node* k = t.jsgraph.Constant(constants[i]);
Node* mod = t.graph()->NewNode(t.simplified()->NumberModulus(), t.p0,
k);
Node* trunc = t.graph()->NewNode(t.simplified()->NumberToUint32(),
mod);
- t.Return(trunc);
+ Node* ret = t.Return(trunc);
t.Lower();
- CHECK_EQ(IrOpcode::kUint32Mod, mod->opcode());
+ CHECK_EQ(IrOpcode::kUint32Mod, ret->InputAt(0)->opcode());
}
}
@@ -1916,45 +1927,3 @@
CHECK_EQ(IrOpcode::kFloat64Mod, mod->opcode()); // Pesky -0 behavior.
}
}
-
-
-TEST(NumberModulus_Uint32) {
- double constants[] = {1, 3, 100, 1000, 100998348};
-
- for (size_t i = 0; i < arraysize(constants); i++) {
- TestingGraph t(Type::Unsigned32());
- Node* k = t.jsgraph.Constant(constants[i]);
- Node* mod = t.graph()->NewNode(t.simplified()->NumberModulus(), t.p0,
k);
- t.Return(mod);
- t.Lower();
-
- CHECK_EQ(IrOpcode::kUint32Mod, mod->opcode());
- }
-}
-
-
-TEST(NumberModulus_BadConstants) {
- int32_t constants[] = {-1, 0};
-
- for (size_t i = 0; i < arraysize(constants); i++) {
- TestingGraph t(Type::Signed32());
- Node* k = t.jsgraph.Constant(constants[i]);
- Node* mod = t.graph()->NewNode(t.simplified()->NumberModulus(), t.p0,
k);
- Node* trunc = t.graph()->NewNode(t.simplified()->NumberToInt32(), mod);
- t.Return(trunc);
- t.Lower();
-
- CHECK_EQ(IrOpcode::kFloat64Mod, mod->opcode());
- }
-
- {
- TestingGraph t(Type::Unsigned32());
- Node* k = t.jsgraph.Constant(0);
- Node* mod = t.graph()->NewNode(t.simplified()->NumberModulus(), t.p0,
k);
- Node* trunc = t.graph()->NewNode(t.simplified()->NumberToUint32(),
mod);
- t.Return(trunc);
- t.Lower();
-
- CHECK_EQ(IrOpcode::kFloat64Mod, mod->opcode());
- }
-}
=======================================
---
/branches/bleeding_edge/test/unittests/compiler/machine-operator-unittest.cc
Fri Oct 24 13:06:48 2014 UTC
+++
/branches/bleeding_edge/test/unittests/compiler/machine-operator-unittest.cc
Tue Oct 28 13:56:26 2014 UTC
@@ -158,6 +158,7 @@
const Operator* (MachineOperatorBuilder::*constructor)();
IrOpcode::Value opcode;
int value_input_count;
+ int control_input_count;
int value_output_count;
};
@@ -168,43 +169,41 @@
const PureOperator kPureOperators[] = {
-#define PURE(Name, input_count, output_count) \
- { \
- &MachineOperatorBuilder::Name, IrOpcode::k##Name, input_count, \
- output_count \
+#define PURE(Name, value_input_count, control_input_count,
value_output_count) \
+
{
\
+ &MachineOperatorBuilder::Name, IrOpcode::k##Name,
value_input_count, \
+ control_input_count,
value_output_count \
}
- PURE(Word32And, 2, 1), PURE(Word32Or, 2, 1),
- PURE(Word32Xor, 2, 1), PURE(Word32Shl, 2, 1),
- PURE(Word32Shr, 2, 1), PURE(Word32Sar, 2, 1),
- PURE(Word32Ror, 2, 1), PURE(Word32Equal, 2, 1),
- PURE(Word64And, 2, 1), PURE(Word64Or, 2, 1),
- PURE(Word64Xor, 2, 1), PURE(Word64Shl, 2, 1),
- PURE(Word64Shr, 2, 1), PURE(Word64Sar, 2, 1),
- PURE(Word64Ror, 2, 1), PURE(Word64Equal, 2, 1),
- PURE(Int32Add, 2, 1), PURE(Int32AddWithOverflow, 2, 2),
- PURE(Int32Sub, 2, 1), PURE(Int32SubWithOverflow, 2, 2),
- PURE(Int32Mul, 2, 1), PURE(Int32MulHigh, 2, 1),
- PURE(Int32Div, 2, 1), PURE(Uint32Div, 2, 1),
- PURE(Int32Mod, 2, 1), PURE(Uint32Mod, 2, 1),
- PURE(Int32LessThan, 2, 1), PURE(Int32LessThanOrEqual, 2, 1),
- PURE(Uint32LessThan, 2, 1), PURE(Uint32LessThanOrEqual, 2,
1),
- PURE(Int64Add, 2, 1), PURE(Int64Sub, 2, 1),
- PURE(Int64Mul, 2, 1), PURE(Int64Div, 2, 1),
- PURE(Uint64Div, 2, 1), PURE(Int64Mod, 2, 1),
- PURE(Uint64Mod, 2, 1), PURE(Int64LessThan, 2, 1),
- PURE(Int64LessThanOrEqual, 2, 1), PURE(Uint64LessThan, 2, 1),
- PURE(ChangeFloat32ToFloat64, 1, 1), PURE(ChangeFloat64ToInt32, 1, 1),
- PURE(ChangeFloat64ToUint32, 1, 1), PURE(ChangeInt32ToInt64, 1, 1),
- PURE(ChangeUint32ToFloat64, 1, 1), PURE(ChangeUint32ToUint64, 1, 1),
- PURE(TruncateFloat64ToFloat32, 1, 1), PURE(TruncateFloat64ToInt32, 1,
1),
- PURE(TruncateInt64ToInt32, 1, 1), PURE(Float64Add, 2, 1),
- PURE(Float64Sub, 2, 1), PURE(Float64Mul, 2, 1),
- PURE(Float64Div, 2, 1), PURE(Float64Mod, 2, 1),
- PURE(Float64Sqrt, 1, 1), PURE(Float64Equal, 2, 1),
- PURE(Float64LessThan, 2, 1), PURE(Float64LessThanOrEqual, 2,
1),
- PURE(LoadStackPointer, 0, 1), PURE(Float64Floor, 1, 1),
- PURE(Float64Ceil, 1, 1), PURE(Float64RoundTruncate, 1, 1),
- PURE(Float64RoundTiesAway, 1, 1),
+ PURE(Word32And, 2, 0, 1), PURE(Word32Or, 2, 0, 1), PURE(Word32Xor, 2,
0, 1),
+ PURE(Word32Shl, 2, 0, 1), PURE(Word32Shr, 2, 0, 1),
+ PURE(Word32Sar, 2, 0, 1), PURE(Word32Ror, 2, 0, 1),
+ PURE(Word32Equal, 2, 0, 1), PURE(Word64And, 2, 0, 1),
+ PURE(Word64Or, 2, 0, 1), PURE(Word64Xor, 2, 0, 1), PURE(Word64Shl, 2,
0, 1),
+ PURE(Word64Shr, 2, 0, 1), PURE(Word64Sar, 2, 0, 1),
+ 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), PURE(Uint32Div, 2, 1, 1), PURE(Int32Mod, 2,
1, 1),
+ PURE(Uint32Mod, 2, 1, 1), PURE(Int32LessThan, 2, 0, 1),
+ PURE(Int32LessThanOrEqual, 2, 0, 1), PURE(Uint32LessThan, 2, 0, 1),
+ PURE(Uint32LessThanOrEqual, 2, 0, 1), PURE(Int64Add, 2, 0, 1),
+ PURE(Int64Sub, 2, 0, 1), PURE(Int64Mul, 2, 0, 1), PURE(Int64Div, 2, 0,
1),
+ PURE(Uint64Div, 2, 0, 1), PURE(Int64Mod, 2, 0, 1), PURE(Uint64Mod, 2,
0, 1),
+ PURE(Int64LessThan, 2, 0, 1), PURE(Int64LessThanOrEqual, 2, 0, 1),
+ PURE(Uint64LessThan, 2, 0, 1), PURE(ChangeFloat32ToFloat64, 1, 0, 1),
+ PURE(ChangeFloat64ToInt32, 1, 0, 1), PURE(ChangeFloat64ToUint32, 1, 0,
1),
+ PURE(ChangeInt32ToInt64, 1, 0, 1), PURE(ChangeUint32ToFloat64, 1, 0,
1),
+ PURE(ChangeUint32ToUint64, 1, 0, 1),
+ PURE(TruncateFloat64ToFloat32, 1, 0, 1),
+ PURE(TruncateFloat64ToInt32, 1, 0, 1), PURE(TruncateInt64ToInt32, 1,
0, 1),
+ PURE(Float64Add, 2, 0, 1), PURE(Float64Sub, 2, 0, 1),
+ PURE(Float64Mul, 2, 0, 1), PURE(Float64Div, 2, 0, 1),
+ PURE(Float64Mod, 2, 0, 1), PURE(Float64Sqrt, 1, 0, 1),
+ PURE(Float64Equal, 2, 0, 1), PURE(Float64LessThan, 2, 0, 1),
+ PURE(Float64LessThanOrEqual, 2, 0, 1), PURE(LoadStackPointer, 0, 0, 1),
+ PURE(Float64Floor, 1, 0, 1), PURE(Float64Ceil, 1, 0, 1),
+ PURE(Float64RoundTruncate, 1, 0, 1), PURE(Float64RoundTiesAway, 1, 0,
1)
#undef PURE
};
@@ -229,8 +228,10 @@
EXPECT_EQ(pop.value_input_count,
OperatorProperties::GetValueInputCount(op));
EXPECT_EQ(0, OperatorProperties::GetEffectInputCount(op));
- EXPECT_EQ(0, OperatorProperties::GetControlInputCount(op));
- EXPECT_EQ(pop.value_input_count,
OperatorProperties::GetTotalInputCount(op));
+ EXPECT_EQ(pop.control_input_count,
+ OperatorProperties::GetControlInputCount(op));
+ EXPECT_EQ(pop.value_input_count + pop.control_input_count,
+ OperatorProperties::GetTotalInputCount(op));
EXPECT_EQ(pop.value_output_count,
OperatorProperties::GetValueOutputCount(op));
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.