Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1029)

Unified Diff: test/cctest/compiler/test-simplified-lowering.cc

Issue 620553008: Lower NumberMultiply, NumberDivide, and NumberModulus to Int32Mul, Int32[U]Div, and Int32[U]Mod whe… (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Add mjsunit and cctests. Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: test/cctest/compiler/test-simplified-lowering.cc
diff --git a/test/cctest/compiler/test-simplified-lowering.cc b/test/cctest/compiler/test-simplified-lowering.cc
index 291f749fb1683fb85fade9d147c60f72fe426ff5..13394df8afa36612e0ba7b0c45bb1789398d4437 100644
--- a/test/cctest/compiler/test-simplified-lowering.cc
+++ b/test/cctest/compiler/test-simplified-lowering.cc
@@ -58,6 +58,13 @@ class SimplifiedLoweringTester : public GraphBuilderTester<ReturnType> {
typer.Run(jsgraph.graph(), MaybeHandle<Context>());
lowering.LowerAllNodes();
+ {
+ FILE* dot_file = fopen("/tmp/test-lowered.dot", "w+");
Michael Starzinger 2014/10/08 09:01:28 Looks like a left-over, let's drop it again.
titzer 2014/10/08 09:12:29 Done.
+ OFStream dot_of(dot_file);
+ dot_of << AsDOT(*jsgraph.graph());
+ fclose(dot_file);
+ }
+
Zone* zone = this->zone();
CompilationInfo info(zone->isolate(), zone);
Linkage linkage(
@@ -1577,6 +1584,79 @@ TEST(RunNumberDivide_minus_1_TruncatingToInt32) {
}
+TEST(NumberMultiply_TruncatingToInt32) {
+ int32_t constants[] = {-100, -10, -1, 0, 1, 100, 1000};
+
+ for (size_t i = 0; i < arraysize(constants); i++) {
+ TestingGraph t(Type::Signed32());
+ Node* k = t.jsgraph.Constant(constants[i]);
+ Node* mul = t.graph()->NewNode(t.simplified()->NumberMultiply(), t.p0, k);
+ Node* trunc = t.graph()->NewNode(t.simplified()->NumberToInt32(), mul);
+ t.Return(trunc);
+ t.Lower();
+
+ CHECK_EQ(IrOpcode::kInt32Mul, mul->opcode());
+ }
+}
+
+
+TEST(RunNumberMultiply_TruncatingToInt32) {
+ int32_t constants[] = {-100, -10, -1, 0, 1, 100, 1000, 3000999};
+
+ for (size_t i = 0; i < arraysize(constants); i++) {
+ double k = static_cast<double>(constants[i]);
+ SimplifiedLoweringTester<Object*> t(kMachAnyTagged);
+ Node* num = t.NumberToInt32(t.Parameter(0));
+ Node* mul = t.NumberMultiply(num, t.jsgraph.Constant(k));
+ Node* trunc = t.NumberToInt32(mul);
+ t.Return(trunc);
+
+ if (Pipeline::SupportedTarget()) {
+ t.LowerAllNodesAndLowerChanges();
+ t.GenerateCode();
+
+ FOR_INT32_INPUTS(i) {
+ Handle<HeapNumber> num = t.factory()->NewHeapNumber(*i);
+ int32_t x = DoubleToInt32(static_cast<double>(*i) * k);
+ Handle<HeapNumber> expected =
+ t.factory()->NewHeapNumber(static_cast<double>(x));
+ Object* result = t.Call(*num);
+ CHECK(expected->SameValue(result));
+ }
+ }
+ }
+}
+
+
+TEST(RunNumberMultiply_TruncatingToUint32) {
+ uint32_t constants[] = {0, 1, 2, 3, 4, 100, 1000, 1024, 2048, 3000999};
+
+ for (size_t i = 0; i < arraysize(constants); i++) {
+ double k = static_cast<double>(constants[i]);
+ SimplifiedLoweringTester<Object*> t(kMachAnyTagged);
+ Node* num = t.NumberToUint32(t.Parameter(0));
+ Node* mul = t.NumberMultiply(num, t.jsgraph.Constant(k));
+ Node* trunc = t.NumberToUint32(mul);
+ t.Return(trunc);
+
+ if (Pipeline::SupportedTarget()) {
+ t.LowerAllNodesAndLowerChanges();
+ t.GenerateCode();
+
+ FOR_UINT32_INPUTS(i) {
+ Handle<HeapNumber> num =
+ t.factory()->NewHeapNumber(static_cast<double>(*i));
+ uint32_t x = DoubleToUint32(static_cast<double>(*i) * k);
+ Handle<HeapNumber> expected =
+ t.factory()->NewHeapNumber(static_cast<double>(x));
+ Object* result = t.Call(*num);
+ CHECK(expected->SameValue(result));
+ }
+ }
+ }
+}
+
+
TEST(RunNumberDivide_2_TruncatingToUint32) {
SimplifiedLoweringTester<Object*> t(kMachAnyTagged);
Node* num = t.NumberToUint32(t.Parameter(0));
@@ -1586,18 +1666,12 @@ TEST(RunNumberDivide_2_TruncatingToUint32) {
if (Pipeline::SupportedTarget()) {
t.LowerAllNodesAndLowerChanges();
- {
- FILE* dot_file = fopen("/tmp/test.dot", "w+");
- OFStream dot_of(dot_file);
- dot_of << AsDOT(*t.jsgraph.graph());
- fclose(dot_file);
- }
t.GenerateCode();
FOR_UINT32_INPUTS(i) {
Handle<HeapNumber> num =
t.factory()->NewHeapNumber(static_cast<double>(*i));
- uint32_t x = *i / 2;
+ uint32_t x = DoubleToUint32(static_cast<double>(*i / 2.0));
// TODO(titzer): make calls to NewHeapNumber work in cctests.
if (x >= static_cast<uint32_t>(Smi::kMaxValue)) continue;
Handle<HeapNumber> expected =
@@ -1607,3 +1681,287 @@ TEST(RunNumberDivide_2_TruncatingToUint32) {
}
}
}
+
+
+TEST(NumberMultiply_ConstantOutOfRange) {
+ TestingGraph t(Type::Signed32());
+ Node* k = t.jsgraph.Constant(1000000023);
+ Node* mul = t.graph()->NewNode(t.simplified()->NumberMultiply(), t.p0, k);
+ Node* trunc = t.graph()->NewNode(t.simplified()->NumberToInt32(), mul);
+ t.Return(trunc);
+ t.Lower();
+
+ CHECK_EQ(IrOpcode::kFloat64Mul, mul->opcode());
+}
+
+
+TEST(NumberMultiply_NonTruncating) {
+ TestingGraph t(Type::Signed32());
+ Node* k = t.jsgraph.Constant(111);
+ Node* mul = t.graph()->NewNode(t.simplified()->NumberMultiply(), t.p0, k);
+ t.Return(mul);
+ t.Lower();
+
+ CHECK_EQ(IrOpcode::kFloat64Mul, mul->opcode());
+}
+
+
+TEST(NumberDivide_TruncatingToInt32) {
+ int32_t constants[] = {-100, -10, 1, 4, 100, 1000};
+
+ for (size_t i = 0; i < arraysize(constants); i++) {
+ 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);
+ t.Lower();
+
+ CHECK_EQ(IrOpcode::kInt32Div, div->opcode());
+ }
+}
+
+
+TEST(RunNumberDivide_TruncatingToInt32) {
+ int32_t constants[] = {-100, -10, -1, 1, 2, 100, 1000, 1024, 2048};
+
+ for (size_t i = 0; i < arraysize(constants); i++) {
+ int32_t k = constants[i];
+ SimplifiedLoweringTester<Object*> t(kMachAnyTagged);
+ Node* num = t.NumberToInt32(t.Parameter(0));
+ Node* div = t.NumberDivide(num, t.jsgraph.Constant(k));
+ Node* trunc = t.NumberToInt32(div);
+ t.Return(trunc);
+
+ if (Pipeline::SupportedTarget()) {
+ t.LowerAllNodesAndLowerChanges();
+ t.GenerateCode();
+
+ FOR_INT32_INPUTS(i) {
+ if (*i == INT_MAX) continue; // exclude max int.
+ Handle<HeapNumber> num = t.factory()->NewHeapNumber(*i);
+ int32_t x = DoubleToInt32(static_cast<double>(*i) / k);
+ Handle<HeapNumber> expected = t.factory()->NewHeapNumber(x);
+ Object* result = t.Call(*num);
+ CHECK(expected->SameValue(result));
+ }
+ }
+ }
+}
+
+
+TEST(NumberDivide_TruncatingToUint32) {
+ 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* div = t.graph()->NewNode(t.simplified()->NumberDivide(), t.p0, k);
+ Node* trunc = t.graph()->NewNode(t.simplified()->NumberToUint32(), div);
+ t.Return(trunc);
+ t.Lower();
+
+ CHECK_EQ(IrOpcode::kUint32Div, div->opcode());
+ }
+}
+
+
+TEST(RunNumberDivide_TruncatingToUint32) {
+ uint32_t constants[] = {100, 10, 1, 1, 2, 4, 1000, 1024, 2048};
+
+ for (size_t i = 0; i < arraysize(constants); i++) {
+ uint32_t k = constants[i];
+ SimplifiedLoweringTester<Object*> t(kMachAnyTagged);
+ Node* num = t.NumberToUint32(t.Parameter(0));
+ Node* div = t.NumberDivide(num, t.jsgraph.Constant(static_cast<double>(k)));
+ Node* trunc = t.NumberToUint32(div);
+ t.Return(trunc);
+
+ if (Pipeline::SupportedTarget()) {
+ t.LowerAllNodesAndLowerChanges();
+ t.GenerateCode();
+
+ FOR_UINT32_INPUTS(i) {
+ Handle<HeapNumber> num =
+ t.factory()->NewHeapNumber(static_cast<double>(*i));
+ Handle<HeapNumber> expected =
+ t.factory()->NewHeapNumber(static_cast<double>(*i / k));
+ Object* result = t.Call(*num);
+ CHECK(expected->SameValue(result));
+ }
+ }
+ }
+}
+
+
+TEST(NumberDivide_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* div = t.graph()->NewNode(t.simplified()->NumberDivide(), t.p0, k);
+ Node* trunc = t.graph()->NewNode(t.simplified()->NumberToInt32(), div);
+ t.Return(trunc);
+ t.Lower();
+
+ CHECK_EQ(IrOpcode::kFloat64Div, div->opcode());
+ }
+
+ {
+ 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);
+ t.Lower();
+
+ CHECK_EQ(IrOpcode::kFloat64Div, div->opcode());
+ }
+}
+
+
+TEST(NumberModulus_TruncatingToInt32) {
+ int32_t constants[] = {-100, -10, 1, 4, 100, 1000};
+
+ 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::kInt32Mod, mod->opcode());
+ }
+}
+
+
+TEST(RunNumberModulus_TruncatingToInt32) {
+ int32_t constants[] = {-100, -10, -1, 1, 2, 100, 1000, 1024, 2048};
+
+ for (size_t i = 0; i < arraysize(constants); i++) {
+ int32_t k = constants[i];
+ SimplifiedLoweringTester<Object*> t(kMachAnyTagged);
+ Node* num = t.NumberToInt32(t.Parameter(0));
+ Node* mod = t.NumberModulus(num, t.jsgraph.Constant(k));
+ Node* trunc = t.NumberToInt32(mod);
+ t.Return(trunc);
+
+ if (Pipeline::SupportedTarget()) {
+ t.LowerAllNodesAndLowerChanges();
+ t.GenerateCode();
+
+ FOR_INT32_INPUTS(i) {
+ if (*i == INT_MAX) continue; // exclude max int.
+ Handle<HeapNumber> num = t.factory()->NewHeapNumber(*i);
+ int32_t x = DoubleToInt32(std::fmod(static_cast<double>(*i), k));
+ Handle<HeapNumber> expected = t.factory()->NewHeapNumber(x);
+ Object* result = t.Call(*num);
+ CHECK(expected->SameValue(result));
+ }
+ }
+ }
+}
+
+
+TEST(NumberModulus_TruncatingToUint32) {
+ 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);
+ Node* trunc = t.graph()->NewNode(t.simplified()->NumberToUint32(), mod);
+ t.Return(trunc);
+ t.Lower();
+
+ CHECK_EQ(IrOpcode::kUint32Mod, mod->opcode());
+ }
+}
+
+
+TEST(RunNumberModulus_TruncatingToUint32) {
+ uint32_t constants[] = {1, 2, 100, 1000, 1024, 2048};
+
+ for (size_t i = 0; i < arraysize(constants); i++) {
+ uint32_t k = constants[i];
+ SimplifiedLoweringTester<Object*> t(kMachAnyTagged);
+ Node* num = t.NumberToUint32(t.Parameter(0));
+ Node* mod =
+ t.NumberModulus(num, t.jsgraph.Constant(static_cast<double>(k)));
+ Node* trunc = t.NumberToUint32(mod);
+ t.Return(trunc);
+
+ if (Pipeline::SupportedTarget()) {
+ t.LowerAllNodesAndLowerChanges();
+ t.GenerateCode();
+
+ FOR_UINT32_INPUTS(i) {
+ Handle<HeapNumber> num =
+ t.factory()->NewHeapNumber(static_cast<double>(*i));
+ Handle<HeapNumber> expected =
+ t.factory()->NewHeapNumber(static_cast<double>(*i % k));
+ Object* result = t.Call(*num);
+ CHECK(expected->SameValue(result));
+ }
+ }
+ }
+}
+
+
+TEST(NumberModulus_Int32) {
+ int32_t constants[] = {-100, -10, 1, 4, 100, 1000};
+
+ 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);
+ t.Return(mod);
+ t.Lower();
+
+ 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());
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698