| 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..b75ed58abbef291185407b27d1aad139da336b27 100644
|
| --- a/test/cctest/compiler/test-simplified-lowering.cc
|
| +++ b/test/cctest/compiler/test-simplified-lowering.cc
|
| @@ -69,6 +69,15 @@ class SimplifiedLoweringTester : public GraphBuilderTester<ReturnType> {
|
| Verifier::Run(this->graph());
|
| }
|
|
|
| + void CheckNumberCall(double expected, double input) {
|
| + // TODO(titzer): make calls to NewNumber work in cctests.
|
| + if (expected <= Smi::kMinValue) return;
|
| + if (expected >= Smi::kMaxValue) return;
|
| + Handle<Object> num = factory()->NewNumber(input);
|
| + Object* result = this->Call(*num);
|
| + CHECK(factory()->NewNumber(expected)->SameValue(result));
|
| + }
|
| +
|
| Factory* factory() { return this->isolate()->factory(); }
|
| Heap* heap() { return this->isolate()->heap(); }
|
| };
|
| @@ -1564,14 +1573,72 @@ TEST(RunNumberDivide_minus_1_TruncatingToInt32) {
|
| t.GenerateCode();
|
|
|
| FOR_INT32_INPUTS(i) {
|
| - Handle<HeapNumber> num = t.factory()->NewHeapNumber(*i);
|
| int32_t x = 0 - *i;
|
| - // TODO(titzer): make calls to NewHeapNumber work in cctests.
|
| - if (x <= Smi::kMinValue) continue;
|
| - if (x >= Smi::kMaxValue) continue;
|
| - Handle<HeapNumber> expected = t.factory()->NewHeapNumber(x);
|
| - Object* result = t.Call(*num);
|
| - CHECK(expected->SameValue(result));
|
| + t.CheckNumberCall(static_cast<double>(x), static_cast<double>(*i));
|
| + }
|
| + }
|
| +}
|
| +
|
| +
|
| +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) {
|
| + int32_t x = DoubleToInt32(static_cast<double>(*i) * k);
|
| + t.CheckNumberCall(static_cast<double>(x), static_cast<double>(*i));
|
| + }
|
| + }
|
| + }
|
| +}
|
| +
|
| +
|
| +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) {
|
| + uint32_t x = DoubleToUint32(static_cast<double>(*i) * k);
|
| + t.CheckNumberCall(static_cast<double>(x), static_cast<double>(*i));
|
| + }
|
| }
|
| }
|
| }
|
| @@ -1586,24 +1653,281 @@ 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;
|
| - // TODO(titzer): make calls to NewHeapNumber work in cctests.
|
| - if (x >= static_cast<uint32_t>(Smi::kMaxValue)) continue;
|
| - Handle<HeapNumber> expected =
|
| - t.factory()->NewHeapNumber(static_cast<double>(x));
|
| - Object* result = t.Call(*num);
|
| - CHECK(expected->SameValue(result));
|
| + uint32_t x = DoubleToUint32(static_cast<double>(*i / 2.0));
|
| + t.CheckNumberCall(static_cast<double>(x), static_cast<double>(*i));
|
| + }
|
| + }
|
| +}
|
| +
|
| +
|
| +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.
|
| + int32_t x = DoubleToInt32(static_cast<double>(*i) / k);
|
| + t.CheckNumberCall(static_cast<double>(x), static_cast<double>(*i));
|
| + }
|
| + }
|
| + }
|
| +}
|
| +
|
| +
|
| +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) {
|
| + uint32_t x = *i / k;
|
| + t.CheckNumberCall(static_cast<double>(x), static_cast<double>(*i));
|
| + }
|
| }
|
| }
|
| }
|
| +
|
| +
|
| +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.
|
| + int32_t x = DoubleToInt32(std::fmod(static_cast<double>(*i), k));
|
| + t.CheckNumberCall(static_cast<double>(x), static_cast<double>(*i));
|
| + }
|
| + }
|
| + }
|
| +}
|
| +
|
| +
|
| +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) {
|
| + uint32_t x = *i % k;
|
| + t.CheckNumberCall(static_cast<double>(x), static_cast<double>(*i));
|
| + }
|
| + }
|
| + }
|
| +}
|
| +
|
| +
|
| +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());
|
| + }
|
| +}
|
|
|