X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fv8%2Ftest%2Fcctest%2Fcompiler%2Ftest-simplified-lowering.cc;h=96fb9650e7e27e8bee05fefe7a0d252d81274c8a;hb=3545e9f2671f595d2a2f3ee75ca0393b01e35ef6;hp=62101981564bc14516de77f18b7aaeefc3849808;hpb=7d210d4c7e9ba36e635eabc5b5780495f8a63292;p=platform%2Fframework%2Fweb%2Fcrosswalk.git diff --git a/src/v8/test/cctest/compiler/test-simplified-lowering.cc b/src/v8/test/cctest/compiler/test-simplified-lowering.cc index 6210198..96fb965 100644 --- a/src/v8/test/cctest/compiler/test-simplified-lowering.cc +++ b/src/v8/test/cctest/compiler/test-simplified-lowering.cc @@ -4,6 +4,7 @@ #include +#include "src/compiler/access-builder.h" #include "src/compiler/control-builders.h" #include "src/compiler/generic-node-inl.h" #include "src/compiler/graph-visualizer.h" @@ -11,7 +12,6 @@ #include "src/compiler/pipeline.h" #include "src/compiler/representation-change.h" #include "src/compiler/simplified-lowering.h" -#include "src/compiler/simplified-node-factory.h" #include "src/compiler/typer.h" #include "src/compiler/verifier.h" #include "src/execution.h" @@ -29,19 +29,20 @@ using namespace v8::internal::compiler; template class SimplifiedLoweringTester : public GraphBuilderTester { public: - SimplifiedLoweringTester(MachineType p0 = kMachineLast, - MachineType p1 = kMachineLast, - MachineType p2 = kMachineLast, - MachineType p3 = kMachineLast, - MachineType p4 = kMachineLast) + SimplifiedLoweringTester(MachineType p0 = kMachNone, + MachineType p1 = kMachNone, + MachineType p2 = kMachNone, + MachineType p3 = kMachNone, + MachineType p4 = kMachNone) : GraphBuilderTester(p0, p1, p2, p3, p4), typer(this->zone()), - source_positions(this->graph()), - jsgraph(this->graph(), this->common(), &typer), - lowering(&jsgraph, &source_positions) {} + javascript(this->zone()), + jsgraph(this->graph(), this->common(), &javascript, &typer, + this->machine()), + lowering(&jsgraph) {} Typer typer; - SourcePositionTable source_positions; + JSOperatorBuilder javascript; JSGraph jsgraph; SimplifiedLowering lowering; @@ -55,47 +56,64 @@ class SimplifiedLoweringTester : public GraphBuilderTester { }; -// TODO(dcarney): find a home for these functions. -namespace { - -FieldAccess ForJSObjectMap() { - FieldAccess access = {kTaggedBase, JSObject::kMapOffset, Handle(), - Type::Any(), kMachineTagged}; - return access; -} - - -FieldAccess ForJSObjectProperties() { - FieldAccess access = {kTaggedBase, JSObject::kPropertiesOffset, - Handle(), Type::Any(), kMachineTagged}; - return access; -} - +#ifndef V8_TARGET_ARCH_ARM64 +// TODO(titzer): these result in a stub call that doesn't work on ARM64. +// TODO(titzer): factor these tests out to test-run-simplifiedops.cc. +// TODO(titzer): test tagged representation for input to NumberToInt32. +TEST(RunNumberToInt32_float64) { + // TODO(titzer): explicit load/stores here are only because of representations + double input; + int32_t result; + SimplifiedLoweringTester t; + FieldAccess load = {kUntaggedBase, 0, Handle(), Type::Number(), + kMachFloat64}; + Node* loaded = t.LoadField(load, t.PointerConstant(&input)); + Node* convert = t.NumberToInt32(loaded); + FieldAccess store = {kUntaggedBase, 0, Handle(), Type::Signed32(), + kMachInt32}; + t.StoreField(store, t.PointerConstant(&result), convert); + t.Return(t.jsgraph.TrueConstant()); + t.LowerAllNodes(); + t.GenerateCode(); -FieldAccess ForArrayBufferBackingStore() { - FieldAccess access = { - kTaggedBase, JSArrayBuffer::kBackingStoreOffset, - Handle(), Type::UntaggedPtr(), - MachineOperatorBuilder::pointer_rep(), - }; - return access; + if (Pipeline::SupportedTarget()) { + FOR_FLOAT64_INPUTS(i) { + input = *i; + int32_t expected = DoubleToInt32(*i); + t.Call(); + CHECK_EQ(expected, result); + } + } } -ElementAccess ForFixedArrayElement() { - ElementAccess access = {kTaggedBase, FixedArray::kHeaderSize, Type::Any(), - kMachineTagged}; - return access; -} - +// TODO(titzer): test tagged representation for input to NumberToUint32. +TEST(RunNumberToUint32_float64) { + // TODO(titzer): explicit load/stores here are only because of representations + double input; + uint32_t result; + SimplifiedLoweringTester t; + FieldAccess load = {kUntaggedBase, 0, Handle(), Type::Number(), + kMachFloat64}; + Node* loaded = t.LoadField(load, t.PointerConstant(&input)); + Node* convert = t.NumberToUint32(loaded); + FieldAccess store = {kUntaggedBase, 0, Handle(), Type::Unsigned32(), + kMachUint32}; + t.StoreField(store, t.PointerConstant(&result), convert); + t.Return(t.jsgraph.TrueConstant()); + t.LowerAllNodes(); + t.GenerateCode(); -ElementAccess ForBackingStoreElement(MachineType rep) { - ElementAccess access = {kUntaggedBase, - kNonHeapObjectHeaderSize - kHeapObjectTag, - Type::Any(), rep}; - return access; -} + if (Pipeline::SupportedTarget()) { + FOR_FLOAT64_INPUTS(i) { + input = *i; + uint32_t expected = DoubleToUint32(*i); + t.Call(); + CHECK_EQ(static_cast(expected), static_cast(result)); + } + } } +#endif // Create a simple JSObject with a unique map. @@ -108,15 +126,15 @@ static Handle TestObject() { TEST(RunLoadMap) { - SimplifiedLoweringTester t(kMachineTagged); - FieldAccess access = ForJSObjectMap(); + SimplifiedLoweringTester t(kMachAnyTagged); + FieldAccess access = AccessBuilder::ForMap(); Node* load = t.LoadField(access, t.Parameter(0)); t.Return(load); t.LowerAllNodes(); + t.GenerateCode(); if (Pipeline::SupportedTarget()) { - t.GenerateCode(); Handle src = TestObject(); Handle src_map(src->map()); Object* result = t.Call(*src); // TODO(titzer): raw pointers in call @@ -126,15 +144,15 @@ TEST(RunLoadMap) { TEST(RunStoreMap) { - SimplifiedLoweringTester t(kMachineTagged, kMachineTagged); - FieldAccess access = ForJSObjectMap(); + SimplifiedLoweringTester t(kMachAnyTagged, kMachAnyTagged); + FieldAccess access = AccessBuilder::ForMap(); t.StoreField(access, t.Parameter(1), t.Parameter(0)); t.Return(t.jsgraph.TrueConstant()); t.LowerAllNodes(); + t.GenerateCode(); if (Pipeline::SupportedTarget()) { - t.GenerateCode(); Handle src = TestObject(); Handle src_map(src->map()); Handle dst = TestObject(); @@ -146,15 +164,15 @@ TEST(RunStoreMap) { TEST(RunLoadProperties) { - SimplifiedLoweringTester t(kMachineTagged); - FieldAccess access = ForJSObjectProperties(); + SimplifiedLoweringTester t(kMachAnyTagged); + FieldAccess access = AccessBuilder::ForJSObjectProperties(); Node* load = t.LoadField(access, t.Parameter(0)); t.Return(load); t.LowerAllNodes(); + t.GenerateCode(); if (Pipeline::SupportedTarget()) { - t.GenerateCode(); Handle src = TestObject(); Handle src_props(src->properties()); Object* result = t.Call(*src); // TODO(titzer): raw pointers in call @@ -164,16 +182,16 @@ TEST(RunLoadProperties) { TEST(RunLoadStoreMap) { - SimplifiedLoweringTester t(kMachineTagged, kMachineTagged); - FieldAccess access = ForJSObjectMap(); + SimplifiedLoweringTester t(kMachAnyTagged, kMachAnyTagged); + FieldAccess access = AccessBuilder::ForMap(); Node* load = t.LoadField(access, t.Parameter(0)); t.StoreField(access, t.Parameter(1), load); t.Return(load); t.LowerAllNodes(); + t.GenerateCode(); if (Pipeline::SupportedTarget()) { - t.GenerateCode(); Handle src = TestObject(); Handle src_map(src->map()); Handle dst = TestObject(); @@ -187,16 +205,18 @@ TEST(RunLoadStoreMap) { TEST(RunLoadStoreFixedArrayIndex) { - SimplifiedLoweringTester t(kMachineTagged); - ElementAccess access = ForFixedArrayElement(); - Node* load = t.LoadElement(access, t.Parameter(0), t.Int32Constant(0)); - t.StoreElement(access, t.Parameter(0), t.Int32Constant(1), load); + SimplifiedLoweringTester t(kMachAnyTagged); + ElementAccess access = AccessBuilder::ForFixedArrayElement(); + Node* load = t.LoadElement(access, t.Parameter(0), t.Int32Constant(0), + t.Int32Constant(2)); + t.StoreElement(access, t.Parameter(0), t.Int32Constant(1), t.Int32Constant(2), + load); t.Return(load); t.LowerAllNodes(); + t.GenerateCode(); if (Pipeline::SupportedTarget()) { - t.GenerateCode(); Handle array = t.factory()->NewFixedArray(2); Handle src = TestObject(); Handle dst = TestObject(); @@ -211,23 +231,25 @@ TEST(RunLoadStoreFixedArrayIndex) { TEST(RunLoadStoreArrayBuffer) { - SimplifiedLoweringTester t(kMachineTagged); + SimplifiedLoweringTester t(kMachAnyTagged); const int index = 12; - ElementAccess buffer_access = ForBackingStoreElement(kMachineWord8); - Node* backing_store = - t.LoadField(ForArrayBufferBackingStore(), t.Parameter(0)); + const int array_length = 2 * index; + ElementAccess buffer_access = + AccessBuilder::ForBackingStoreElement(kMachInt8); + Node* backing_store = t.LoadField( + AccessBuilder::ForJSArrayBufferBackingStore(), t.Parameter(0)); Node* load = - t.LoadElement(buffer_access, backing_store, t.Int32Constant(index)); + t.LoadElement(buffer_access, backing_store, t.Int32Constant(index), + t.Int32Constant(array_length)); t.StoreElement(buffer_access, backing_store, t.Int32Constant(index + 1), - load); + t.Int32Constant(array_length), load); t.Return(t.jsgraph.TrueConstant()); t.LowerAllNodes(); + t.GenerateCode(); if (Pipeline::SupportedTarget()) { - t.GenerateCode(); Handle array = t.factory()->NewJSArrayBuffer(); - const int array_length = 2 * index; Runtime::SetupArrayBufferAllocatingData(t.isolate(), array, array_length); uint8_t* data = reinterpret_cast(array->backing_store()); for (int i = 0; i < array_length; i++) { @@ -249,10 +271,10 @@ TEST(RunLoadStoreArrayBuffer) { TEST(RunLoadFieldFromUntaggedBase) { Smi* smis[] = {Smi::FromInt(1), Smi::FromInt(2), Smi::FromInt(3)}; - for (size_t i = 0; i < ARRAY_SIZE(smis); i++) { + for (size_t i = 0; i < arraysize(smis); i++) { int offset = static_cast(i * sizeof(Smi*)); FieldAccess access = {kUntaggedBase, offset, Handle(), - Type::Integral32(), kMachineTagged}; + Type::Integral32(), kMachAnyTagged}; SimplifiedLoweringTester t; Node* load = t.LoadField(access, t.PointerConstant(smis)); @@ -273,12 +295,12 @@ TEST(RunLoadFieldFromUntaggedBase) { TEST(RunStoreFieldToUntaggedBase) { Smi* smis[] = {Smi::FromInt(1), Smi::FromInt(2), Smi::FromInt(3)}; - for (size_t i = 0; i < ARRAY_SIZE(smis); i++) { + for (size_t i = 0; i < arraysize(smis); i++) { int offset = static_cast(i * sizeof(Smi*)); FieldAccess access = {kUntaggedBase, offset, Handle(), - Type::Integral32(), kMachineTagged}; + Type::Integral32(), kMachAnyTagged}; - SimplifiedLoweringTester t(kMachineTagged); + SimplifiedLoweringTester t(kMachAnyTagged); Node* p0 = t.Parameter(0); t.StoreField(access, t.PointerConstant(smis), p0); t.Return(p0); @@ -300,15 +322,16 @@ TEST(RunLoadElementFromUntaggedBase) { Smi* smis[] = {Smi::FromInt(1), Smi::FromInt(2), Smi::FromInt(3), Smi::FromInt(4), Smi::FromInt(5)}; - for (size_t i = 0; i < ARRAY_SIZE(smis); i++) { // for header sizes - for (size_t j = 0; (i + j) < ARRAY_SIZE(smis); j++) { // for element index + for (size_t i = 0; i < arraysize(smis); i++) { // for header sizes + for (size_t j = 0; (i + j) < arraysize(smis); j++) { // for element index int offset = static_cast(i * sizeof(Smi*)); ElementAccess access = {kUntaggedBase, offset, Type::Integral32(), - kMachineTagged}; + kMachAnyTagged}; SimplifiedLoweringTester t; - Node* load = t.LoadElement(access, t.PointerConstant(smis), - t.Int32Constant(static_cast(j))); + Node* load = t.LoadElement( + access, t.PointerConstant(smis), t.Int32Constant(static_cast(j)), + t.Int32Constant(static_cast(arraysize(smis)))); t.Return(load); t.LowerAllNodes(); @@ -328,16 +351,17 @@ TEST(RunStoreElementFromUntaggedBase) { Smi* smis[] = {Smi::FromInt(1), Smi::FromInt(2), Smi::FromInt(3), Smi::FromInt(4), Smi::FromInt(5)}; - for (size_t i = 0; i < ARRAY_SIZE(smis); i++) { // for header sizes - for (size_t j = 0; (i + j) < ARRAY_SIZE(smis); j++) { // for element index + for (size_t i = 0; i < arraysize(smis); i++) { // for header sizes + for (size_t j = 0; (i + j) < arraysize(smis); j++) { // for element index int offset = static_cast(i * sizeof(Smi*)); ElementAccess access = {kUntaggedBase, offset, Type::Integral32(), - kMachineTagged}; + kMachAnyTagged}; - SimplifiedLoweringTester t(kMachineTagged); + SimplifiedLoweringTester t(kMachAnyTagged); Node* p0 = t.Parameter(0); t.StoreElement(access, t.PointerConstant(smis), - t.Int32Constant(static_cast(j)), p0); + t.Int32Constant(static_cast(j)), + t.Int32Constant(static_cast(arraysize(smis))), p0); t.Return(p0); t.LowerAllNodes(); @@ -403,13 +427,15 @@ class AccessTester : public HandleAndZoneScope { SimplifiedLoweringTester t; Node* ptr = GetBaseNode(&t); - Node* load = t.LoadElement(access, ptr, t.Int32Constant(from_index)); - t.StoreElement(access, ptr, t.Int32Constant(to_index), load); + Node* load = t.LoadElement(access, ptr, t.Int32Constant(from_index), + t.Int32Constant(static_cast(num_elements))); + t.StoreElement(access, ptr, t.Int32Constant(to_index), + t.Int32Constant(static_cast(num_elements)), load); t.Return(t.jsgraph.TrueConstant()); t.LowerAllNodes(); + t.GenerateCode(); if (Pipeline::SupportedTarget()) { - t.GenerateCode(); Object* result = t.Call(); CHECK_EQ(t.isolate()->heap()->true_value(), result); } @@ -429,9 +455,9 @@ class AccessTester : public HandleAndZoneScope { t.StoreField(to_access, ptr, load); t.Return(t.jsgraph.TrueConstant()); t.LowerAllNodes(); + t.GenerateCode(); if (Pipeline::SupportedTarget()) { - t.GenerateCode(); Object* result = t.Call(); CHECK_EQ(t.isolate()->heap()->true_value(), result); } @@ -439,6 +465,8 @@ class AccessTester : public HandleAndZoneScope { // Create and run code that copies the elements from {this} to {that}. void RunCopyElements(AccessTester* that) { +// TODO(titzer): Rewrite this test without StructuredGraphBuilder support. +#if 0 SimplifiedLoweringTester t; Node* one = t.Int32Constant(1); @@ -468,12 +496,13 @@ class AccessTester : public HandleAndZoneScope { index = t.environment()->Pop(); t.Return(t.jsgraph.TrueConstant()); t.LowerAllNodes(); + t.GenerateCode(); if (Pipeline::SupportedTarget()) { - t.GenerateCode(); Object* result = t.Call(); CHECK_EQ(t.isolate()->heap()->true_value(), result); } +#endif } E GetElement(int index) { @@ -559,19 +588,19 @@ static void RunAccessTest(MachineType rep, E* original_elements, size_t num) { TEST(RunAccessTests_uint8) { uint8_t data[] = {0x07, 0x16, 0x25, 0x34, 0x43, 0x99, 0xab, 0x78, 0x89, 0x19, 0x2b, 0x38}; - RunAccessTest(kMachineWord8, data, ARRAY_SIZE(data)); + RunAccessTest(kMachInt8, data, arraysize(data)); } TEST(RunAccessTests_uint16) { uint16_t data[] = {0x071a, 0x162b, 0x253c, 0x344d, 0x435e, 0x7777}; - RunAccessTest(kMachineWord16, data, ARRAY_SIZE(data)); + RunAccessTest(kMachInt16, data, arraysize(data)); } TEST(RunAccessTests_int32) { int32_t data[] = {-211, 211, 628347, 2000000000, -2000000000, -1, -100000034}; - RunAccessTest(kMachineWord32, data, ARRAY_SIZE(data)); + RunAccessTest(kMachInt32, data, arraysize(data)); } @@ -585,13 +614,13 @@ TEST(RunAccessTests_int64) { V8_2PART_INT64(0x30313233, 34353637), V8_2PART_INT64(0xa0a1a2a3, a4a5a6a7), V8_2PART_INT64(0xf0f1f2f3, f4f5f6f7)}; - RunAccessTest(kMachineWord64, data, ARRAY_SIZE(data)); + RunAccessTest(kMachInt64, data, arraysize(data)); } TEST(RunAccessTests_float64) { double data[] = {1.25, -1.25, 2.75, 11.0, 11100.8}; - RunAccessTest(kMachineFloat64, data, ARRAY_SIZE(data)); + RunAccessTest(kMachFloat64, data, arraysize(data)); } @@ -599,7 +628,7 @@ TEST(RunAccessTests_Smi) { Smi* data[] = {Smi::FromInt(-1), Smi::FromInt(-9), Smi::FromInt(0), Smi::FromInt(666), Smi::FromInt(77777), Smi::FromInt(Smi::kMaxValue)}; - RunAccessTest(kMachineTagged, data, ARRAY_SIZE(data)); + RunAccessTest(kMachAnyTagged, data, arraysize(data)); } @@ -607,17 +636,21 @@ TEST(RunAccessTests_Smi) { class TestingGraph : public HandleAndZoneScope, public GraphAndBuilders { public: Typer typer; + JSOperatorBuilder javascript; JSGraph jsgraph; Node* p0; Node* p1; + Node* p2; Node* start; Node* end; Node* ret; - explicit TestingGraph(Type* p0_type, Type* p1_type = Type::None()) + explicit TestingGraph(Type* p0_type, Type* p1_type = Type::None(), + Type* p2_type = Type::None()) : GraphAndBuilders(main_zone()), typer(main_zone()), - jsgraph(graph(), common(), &typer) { + javascript(main_zone()), + jsgraph(graph(), common(), &javascript, &typer, machine()) { start = graph()->NewNode(common()->Start(2)); graph()->SetStart(start); ret = @@ -626,18 +659,20 @@ class TestingGraph : public HandleAndZoneScope, public GraphAndBuilders { graph()->SetEnd(end); p0 = graph()->NewNode(common()->Parameter(0), start); p1 = graph()->NewNode(common()->Parameter(1), start); + p2 = graph()->NewNode(common()->Parameter(2), start); NodeProperties::SetBounds(p0, Bounds(p0_type)); NodeProperties::SetBounds(p1, Bounds(p1_type)); + NodeProperties::SetBounds(p2, Bounds(p2_type)); } - void CheckLoweringBinop(IrOpcode::Value expected, Operator* op) { + void CheckLoweringBinop(IrOpcode::Value expected, const Operator* op) { Node* node = Return(graph()->NewNode(op, p0, p1)); Lower(); CHECK_EQ(expected, node->opcode()); } - void CheckLoweringTruncatedBinop(IrOpcode::Value expected, Operator* op, - Operator* trunc) { + void CheckLoweringTruncatedBinop(IrOpcode::Value expected, const Operator* op, + const Operator* trunc) { Node* node = graph()->NewNode(op, p0, p1); Return(graph()->NewNode(trunc, node)); Lower(); @@ -645,7 +680,7 @@ class TestingGraph : public HandleAndZoneScope, public GraphAndBuilders { } void Lower() { - SimplifiedLowering lowering(&jsgraph, NULL); + SimplifiedLowering lowering(&jsgraph); lowering.LowerAllNodes(); } @@ -658,42 +693,42 @@ class TestingGraph : public HandleAndZoneScope, public GraphAndBuilders { // Inserts the node as the effect input to the return of the graph. void Effect(Node* node) { ret->ReplaceInput(1, node); } - Node* ExampleWithOutput(RepType type) { + Node* ExampleWithOutput(MachineType type) { // TODO(titzer): use parameters with guaranteed representations. - if (type & tInt32) { + if (type & kTypeInt32) { return graph()->NewNode(machine()->Int32Add(), jsgraph.Int32Constant(1), jsgraph.Int32Constant(1)); - } else if (type & tUint32) { + } else if (type & kTypeUint32) { return graph()->NewNode(machine()->Word32Shr(), jsgraph.Int32Constant(1), jsgraph.Int32Constant(1)); - } else if (type & rFloat64) { + } else if (type & kRepFloat64) { return graph()->NewNode(machine()->Float64Add(), jsgraph.Float64Constant(1), jsgraph.Float64Constant(1)); - } else if (type & rBit) { + } else if (type & kRepBit) { return graph()->NewNode(machine()->Word32Equal(), jsgraph.Int32Constant(1), jsgraph.Int32Constant(1)); - } else if (type & rWord64) { + } else if (type & kRepWord64) { return graph()->NewNode(machine()->Int64Add(), Int64Constant(1), Int64Constant(1)); } else { - CHECK(type & rTagged); + CHECK(type & kRepTagged); return p0; } } - Node* Use(Node* node, RepType type) { - if (type & tInt32) { + Node* Use(Node* node, MachineType type) { + if (type & kTypeInt32) { return graph()->NewNode(machine()->Int32LessThan(), node, jsgraph.Int32Constant(1)); - } else if (type & tUint32) { + } else if (type & kTypeUint32) { return graph()->NewNode(machine()->Uint32LessThan(), node, jsgraph.Int32Constant(1)); - } else if (type & rFloat64) { + } else if (type & kRepFloat64) { return graph()->NewNode(machine()->Float64Add(), node, jsgraph.Float64Constant(1)); - } else if (type & rWord64) { + } else if (type & kRepWord64) { return graph()->NewNode(machine()->Int64LessThan(), node, Int64Constant(1)); } else { @@ -707,7 +742,7 @@ class TestingGraph : public HandleAndZoneScope, public GraphAndBuilders { Node* tb = graph()->NewNode(common()->IfTrue(), br); Node* fb = graph()->NewNode(common()->IfFalse(), br); Node* m = graph()->NewNode(common()->Merge(2), tb, fb); - ret->ReplaceInput(NodeProperties::FirstControlIndex(ret), m); + NodeProperties::ReplaceControlInput(ret, m); return br; } @@ -723,9 +758,9 @@ class TestingGraph : public HandleAndZoneScope, public GraphAndBuilders { TEST(LowerBooleanNot_bit_bit) { - // BooleanNot(x: rBit) used as rBit + // BooleanNot(x: kRepBit) used as kRepBit TestingGraph t(Type::Boolean()); - Node* b = t.ExampleWithOutput(rBit); + Node* b = t.ExampleWithOutput(kRepBit); Node* inv = t.graph()->NewNode(t.simplified()->BooleanNot(), b); Node* use = t.Branch(inv); t.Lower(); @@ -738,11 +773,11 @@ TEST(LowerBooleanNot_bit_bit) { TEST(LowerBooleanNot_bit_tagged) { - // BooleanNot(x: rBit) used as rTagged + // BooleanNot(x: kRepBit) used as kRepTagged TestingGraph t(Type::Boolean()); - Node* b = t.ExampleWithOutput(rBit); + Node* b = t.ExampleWithOutput(kRepBit); Node* inv = t.graph()->NewNode(t.simplified()->BooleanNot(), b); - Node* use = t.Use(inv, rTagged); + Node* use = t.Use(inv, kRepTagged); t.Return(use); t.Lower(); CHECK_EQ(IrOpcode::kChangeBitToBool, use->InputAt(0)->opcode()); @@ -755,7 +790,7 @@ TEST(LowerBooleanNot_bit_tagged) { TEST(LowerBooleanNot_tagged_bit) { - // BooleanNot(x: rTagged) used as rBit + // BooleanNot(x: kRepTagged) used as kRepBit TestingGraph t(Type::Boolean()); Node* b = t.p0; Node* inv = t.graph()->NewNode(t.simplified()->BooleanNot(), b); @@ -770,11 +805,11 @@ TEST(LowerBooleanNot_tagged_bit) { TEST(LowerBooleanNot_tagged_tagged) { - // BooleanNot(x: rTagged) used as rTagged + // BooleanNot(x: kRepTagged) used as kRepTagged TestingGraph t(Type::Boolean()); Node* b = t.p0; Node* inv = t.graph()->NewNode(t.simplified()->BooleanNot(), b); - Node* use = t.Use(inv, rTagged); + Node* use = t.Use(inv, kRepTagged); t.Return(use); t.Lower(); CHECK_EQ(IrOpcode::kChangeBitToBool, use->InputAt(0)->opcode()); @@ -786,6 +821,63 @@ TEST(LowerBooleanNot_tagged_tagged) { } +TEST(LowerBooleanToNumber_bit_int32) { + // BooleanToNumber(x: kRepBit) used as kMachInt32 + TestingGraph t(Type::Boolean()); + Node* b = t.ExampleWithOutput(kRepBit); + Node* cnv = t.graph()->NewNode(t.simplified()->BooleanToNumber(), b); + Node* use = t.Use(cnv, kMachInt32); + t.Return(use); + t.Lower(); + CHECK_EQ(b, use->InputAt(0)); +} + + +TEST(LowerBooleanToNumber_tagged_int32) { + // BooleanToNumber(x: kRepTagged) used as kMachInt32 + TestingGraph t(Type::Boolean()); + Node* b = t.p0; + Node* cnv = t.graph()->NewNode(t.simplified()->BooleanToNumber(), b); + Node* use = t.Use(cnv, kMachInt32); + t.Return(use); + t.Lower(); + CHECK_EQ(t.machine()->WordEqual()->opcode(), cnv->opcode()); + CHECK(b == cnv->InputAt(0) || b == cnv->InputAt(1)); + Node* c = t.jsgraph.TrueConstant(); + CHECK(c == cnv->InputAt(0) || c == cnv->InputAt(1)); +} + + +TEST(LowerBooleanToNumber_bit_tagged) { + // BooleanToNumber(x: kRepBit) used as kMachAnyTagged + TestingGraph t(Type::Boolean()); + Node* b = t.ExampleWithOutput(kRepBit); + Node* cnv = t.graph()->NewNode(t.simplified()->BooleanToNumber(), b); + Node* use = t.Use(cnv, kMachAnyTagged); + t.Return(use); + t.Lower(); + CHECK_EQ(b, use->InputAt(0)->InputAt(0)); + CHECK_EQ(IrOpcode::kChangeInt32ToTagged, use->InputAt(0)->opcode()); +} + + +TEST(LowerBooleanToNumber_tagged_tagged) { + // BooleanToNumber(x: kRepTagged) used as kMachAnyTagged + TestingGraph t(Type::Boolean()); + Node* b = t.p0; + Node* cnv = t.graph()->NewNode(t.simplified()->BooleanToNumber(), b); + Node* use = t.Use(cnv, kMachAnyTagged); + t.Return(use); + t.Lower(); + CHECK_EQ(cnv, use->InputAt(0)->InputAt(0)); + CHECK_EQ(IrOpcode::kChangeInt32ToTagged, use->InputAt(0)->opcode()); + CHECK_EQ(t.machine()->WordEqual()->opcode(), cnv->opcode()); + CHECK(b == cnv->InputAt(0) || b == cnv->InputAt(1)); + Node* c = t.jsgraph.TrueConstant(); + CHECK(c == cnv->InputAt(0) || c == cnv->InputAt(1)); +} + + static Type* test_types[] = {Type::Signed32(), Type::Unsigned32(), Type::Number(), Type::Any()}; @@ -815,7 +907,7 @@ TEST(LowerNumberCmp_to_uint32) { TEST(LowerNumberCmp_to_float64) { static Type* types[] = {Type::Number(), Type::Any()}; - for (size_t i = 0; i < ARRAY_SIZE(types); i++) { + for (size_t i = 0; i < arraysize(types); i++) { TestingGraph t(types[i], types[i]); t.CheckLoweringBinop(IrOpcode::kFloat64Equal, @@ -851,7 +943,7 @@ TEST(LowerNumberAddSub_to_uint32) { TEST(LowerNumberAddSub_to_float64) { - for (size_t i = 0; i < ARRAY_SIZE(test_types); i++) { + for (size_t i = 0; i < arraysize(test_types); i++) { TestingGraph t(test_types[i], test_types[i]); t.CheckLoweringBinop(IrOpcode::kFloat64Add, t.simplified()->NumberAdd()); @@ -862,7 +954,7 @@ TEST(LowerNumberAddSub_to_float64) { TEST(LowerNumberDivMod_to_float64) { - for (size_t i = 0; i < ARRAY_SIZE(test_types); i++) { + for (size_t i = 0; i < arraysize(test_types); i++) { TestingGraph t(test_types[i], test_types[i]); t.CheckLoweringBinop(IrOpcode::kFloat64Div, t.simplified()->NumberDivide()); @@ -879,10 +971,10 @@ static void CheckChangeOf(IrOpcode::Value change, Node* of, Node* node) { TEST(LowerNumberToInt32_to_nop) { - // NumberToInt32(x: rTagged | tInt32) used as rTagged + // NumberToInt32(x: kRepTagged | kTypeInt32) used as kRepTagged TestingGraph t(Type::Signed32()); Node* trunc = t.graph()->NewNode(t.simplified()->NumberToInt32(), t.p0); - Node* use = t.Use(trunc, rTagged); + Node* use = t.Use(trunc, kRepTagged); t.Return(use); t.Lower(); CHECK_EQ(t.p0, use->InputAt(0)); @@ -890,10 +982,10 @@ TEST(LowerNumberToInt32_to_nop) { TEST(LowerNumberToInt32_to_ChangeTaggedToFloat64) { - // NumberToInt32(x: rTagged | tInt32) used as rFloat64 + // NumberToInt32(x: kRepTagged | kTypeInt32) used as kRepFloat64 TestingGraph t(Type::Signed32()); Node* trunc = t.graph()->NewNode(t.simplified()->NumberToInt32(), t.p0); - Node* use = t.Use(trunc, rFloat64); + Node* use = t.Use(trunc, kRepFloat64); t.Return(use); t.Lower(); CheckChangeOf(IrOpcode::kChangeTaggedToFloat64, t.p0, use->InputAt(0)); @@ -901,36 +993,59 @@ TEST(LowerNumberToInt32_to_ChangeTaggedToFloat64) { TEST(LowerNumberToInt32_to_ChangeTaggedToInt32) { - // NumberToInt32(x: rTagged | tInt32) used as rWord32 + // NumberToInt32(x: kRepTagged | kTypeInt32) used as kRepWord32 TestingGraph t(Type::Signed32()); Node* trunc = t.graph()->NewNode(t.simplified()->NumberToInt32(), t.p0); - Node* use = t.Use(trunc, tInt32); + Node* use = t.Use(trunc, kTypeInt32); t.Return(use); t.Lower(); CheckChangeOf(IrOpcode::kChangeTaggedToInt32, t.p0, use->InputAt(0)); } -TEST(LowerNumberToInt32_to_ChangeFloat64ToTagged) { - // TODO(titzer): NumberToInt32(x: rFloat64 | tInt32) used as rTagged +TEST(LowerNumberToInt32_to_TruncateFloat64ToInt32) { + // NumberToInt32(x: kRepFloat64) used as kMachInt32 + TestingGraph t(Type::Number()); + Node* p0 = t.ExampleWithOutput(kMachFloat64); + Node* trunc = t.graph()->NewNode(t.simplified()->NumberToInt32(), p0); + Node* use = t.Use(trunc, kMachInt32); + t.Return(use); + t.Lower(); + CheckChangeOf(IrOpcode::kTruncateFloat64ToInt32, p0, use->InputAt(0)); } -TEST(LowerNumberToInt32_to_ChangeFloat64ToInt32) { - // TODO(titzer): NumberToInt32(x: rFloat64 | tInt32) used as rWord32 | tInt32 +TEST(LowerNumberToInt32_to_TruncateFloat64ToInt32_with_change) { + // NumberToInt32(x: kTypeNumber | kRepTagged) used as kMachInt32 + TestingGraph t(Type::Number()); + Node* trunc = t.graph()->NewNode(t.simplified()->NumberToInt32(), t.p0); + Node* use = t.Use(trunc, kMachInt32); + t.Return(use); + t.Lower(); + Node* node = use->InputAt(0); + CHECK_EQ(IrOpcode::kTruncateFloat64ToInt32, node->opcode()); + Node* of = node->InputAt(0); + CHECK_EQ(IrOpcode::kChangeTaggedToFloat64, of->opcode()); + CHECK_EQ(t.p0, of->InputAt(0)); } -TEST(LowerNumberToInt32_to_TruncateFloat64ToInt32) { - // TODO(titzer): NumberToInt32(x: rFloat64) used as rWord32 | tUint32 +TEST(LowerNumberToInt32_to_ChangeFloat64ToTagged) { + // TODO(titzer): NumberToInt32(x: kRepFloat64 | kTypeInt32) used as kRepTagged +} + + +TEST(LowerNumberToInt32_to_ChangeFloat64ToInt32) { + // TODO(titzer): NumberToInt32(x: kRepFloat64 | kTypeInt32) used as kRepWord32 + // | kTypeInt32 } TEST(LowerNumberToUint32_to_nop) { - // NumberToUint32(x: rTagged | tUint32) used as rTagged + // NumberToUint32(x: kRepTagged | kTypeUint32) used as kRepTagged TestingGraph t(Type::Unsigned32()); Node* trunc = t.graph()->NewNode(t.simplified()->NumberToUint32(), t.p0); - Node* use = t.Use(trunc, rTagged); + Node* use = t.Use(trunc, kRepTagged); t.Return(use); t.Lower(); CHECK_EQ(t.p0, use->InputAt(0)); @@ -938,10 +1053,10 @@ TEST(LowerNumberToUint32_to_nop) { TEST(LowerNumberToUint32_to_ChangeTaggedToFloat64) { - // NumberToUint32(x: rTagged | tUint32) used as rWord32 + // NumberToUint32(x: kRepTagged | kTypeUint32) used as kRepWord32 TestingGraph t(Type::Unsigned32()); Node* trunc = t.graph()->NewNode(t.simplified()->NumberToUint32(), t.p0); - Node* use = t.Use(trunc, rFloat64); + Node* use = t.Use(trunc, kRepFloat64); t.Return(use); t.Lower(); CheckChangeOf(IrOpcode::kChangeTaggedToFloat64, t.p0, use->InputAt(0)); @@ -949,28 +1064,57 @@ TEST(LowerNumberToUint32_to_ChangeTaggedToFloat64) { TEST(LowerNumberToUint32_to_ChangeTaggedToUint32) { - // NumberToUint32(x: rTagged | tUint32) used as rWord32 + // NumberToUint32(x: kRepTagged | kTypeUint32) used as kRepWord32 TestingGraph t(Type::Unsigned32()); Node* trunc = t.graph()->NewNode(t.simplified()->NumberToUint32(), t.p0); - Node* use = t.Use(trunc, tUint32); + Node* use = t.Use(trunc, kTypeUint32); t.Return(use); t.Lower(); CheckChangeOf(IrOpcode::kChangeTaggedToUint32, t.p0, use->InputAt(0)); } +TEST(LowerNumberToUint32_to_TruncateFloat64ToInt32) { + // NumberToUint32(x: kRepFloat64) used as kMachUint32 + TestingGraph t(Type::Number()); + Node* p0 = t.ExampleWithOutput(kMachFloat64); + Node* trunc = t.graph()->NewNode(t.simplified()->NumberToUint32(), p0); + Node* use = t.Use(trunc, kMachUint32); + t.Return(use); + t.Lower(); + CheckChangeOf(IrOpcode::kTruncateFloat64ToInt32, p0, use->InputAt(0)); +} + + +TEST(LowerNumberToUint32_to_TruncateFloat64ToInt32_with_change) { + // NumberToInt32(x: kTypeNumber | kRepTagged) used as kMachUint32 + TestingGraph t(Type::Number()); + Node* trunc = t.graph()->NewNode(t.simplified()->NumberToUint32(), t.p0); + Node* use = t.Use(trunc, kMachUint32); + t.Return(use); + t.Lower(); + Node* node = use->InputAt(0); + CHECK_EQ(IrOpcode::kTruncateFloat64ToInt32, node->opcode()); + Node* of = node->InputAt(0); + CHECK_EQ(IrOpcode::kChangeTaggedToFloat64, of->opcode()); + CHECK_EQ(t.p0, of->InputAt(0)); +} + + TEST(LowerNumberToUint32_to_ChangeFloat64ToTagged) { - // TODO(titzer): NumberToUint32(x: rFloat64 | tUint32) used as rTagged + // TODO(titzer): NumberToUint32(x: kRepFloat64 | kTypeUint32) used as + // kRepTagged } TEST(LowerNumberToUint32_to_ChangeFloat64ToUint32) { - // TODO(titzer): NumberToUint32(x: rFloat64 | tUint32) used as rWord32 + // TODO(titzer): NumberToUint32(x: kRepFloat64 | kTypeUint32) used as + // kRepWord32 } TEST(LowerNumberToUint32_to_TruncateFloat64ToUint32) { - // TODO(titzer): NumberToUint32(x: rFloat64) used as rWord32 + // TODO(titzer): NumberToUint32(x: kRepFloat64) used as kRepWord32 } @@ -982,19 +1126,26 @@ TEST(LowerReferenceEqual_to_wordeq) { } -TEST(LowerStringOps_to_rtcalls) { - if (false) { // TODO(titzer): lower StringOps to runtime calls +TEST(LowerStringOps_to_call_and_compare) { + if (Pipeline::SupportedTarget()) { + // These tests need linkage for the calls. TestingGraph t(Type::String(), Type::String()); - t.CheckLoweringBinop(IrOpcode::kCall, t.simplified()->StringEqual()); - t.CheckLoweringBinop(IrOpcode::kCall, t.simplified()->StringLessThan()); - t.CheckLoweringBinop(IrOpcode::kCall, - t.simplified()->StringLessThanOrEqual()); + IrOpcode::Value compare_eq = + static_cast(t.machine()->WordEqual()->opcode()); + IrOpcode::Value compare_lt = + static_cast(t.machine()->IntLessThan()->opcode()); + IrOpcode::Value compare_le = static_cast( + t.machine()->IntLessThanOrEqual()->opcode()); + t.CheckLoweringBinop(compare_eq, t.simplified()->StringEqual()); + t.CheckLoweringBinop(compare_lt, t.simplified()->StringLessThan()); + t.CheckLoweringBinop(compare_le, t.simplified()->StringLessThanOrEqual()); t.CheckLoweringBinop(IrOpcode::kCall, t.simplified()->StringAdd()); } } -void CheckChangeInsertion(IrOpcode::Value expected, RepType from, RepType to) { +void CheckChangeInsertion(IrOpcode::Value expected, MachineType from, + MachineType to) { TestingGraph t(Type::Any()); Node* in = t.ExampleWithOutput(from); Node* use = t.Use(in, to); @@ -1006,26 +1157,31 @@ void CheckChangeInsertion(IrOpcode::Value expected, RepType from, RepType to) { TEST(InsertBasicChanges) { - if (false) { - // TODO(titzer): these changes need the output to have the right type. - CheckChangeInsertion(IrOpcode::kChangeFloat64ToInt32, rFloat64, tInt32); - CheckChangeInsertion(IrOpcode::kChangeFloat64ToUint32, rFloat64, tUint32); - CheckChangeInsertion(IrOpcode::kChangeTaggedToInt32, rTagged, tInt32); - CheckChangeInsertion(IrOpcode::kChangeTaggedToUint32, rTagged, tUint32); - } + CheckChangeInsertion(IrOpcode::kChangeFloat64ToInt32, kRepFloat64, + kTypeInt32); + CheckChangeInsertion(IrOpcode::kChangeFloat64ToUint32, kRepFloat64, + kTypeUint32); + CheckChangeInsertion(IrOpcode::kChangeTaggedToInt32, kRepTagged, kTypeInt32); + CheckChangeInsertion(IrOpcode::kChangeTaggedToUint32, kRepTagged, + kTypeUint32); - CheckChangeInsertion(IrOpcode::kChangeFloat64ToTagged, rFloat64, rTagged); - CheckChangeInsertion(IrOpcode::kChangeTaggedToFloat64, rTagged, rFloat64); + CheckChangeInsertion(IrOpcode::kChangeFloat64ToTagged, kRepFloat64, + kRepTagged); + CheckChangeInsertion(IrOpcode::kChangeTaggedToFloat64, kRepTagged, + kRepFloat64); - CheckChangeInsertion(IrOpcode::kChangeInt32ToFloat64, tInt32, rFloat64); - CheckChangeInsertion(IrOpcode::kChangeInt32ToTagged, tInt32, rTagged); + CheckChangeInsertion(IrOpcode::kChangeInt32ToFloat64, kTypeInt32, + kRepFloat64); + CheckChangeInsertion(IrOpcode::kChangeInt32ToTagged, kTypeInt32, kRepTagged); - CheckChangeInsertion(IrOpcode::kChangeUint32ToFloat64, tUint32, rFloat64); - CheckChangeInsertion(IrOpcode::kChangeUint32ToTagged, tUint32, rTagged); + CheckChangeInsertion(IrOpcode::kChangeUint32ToFloat64, kTypeUint32, + kRepFloat64); + CheckChangeInsertion(IrOpcode::kChangeUint32ToTagged, kTypeUint32, + kRepTagged); } -static void CheckChangesAroundBinop(TestingGraph* t, Operator* op, +static void CheckChangesAroundBinop(TestingGraph* t, const Operator* op, IrOpcode::Value input_change, IrOpcode::Value output_change) { Node* binop = t->graph()->NewNode(op, t->p0, t->p1); @@ -1043,13 +1199,13 @@ static void CheckChangesAroundBinop(TestingGraph* t, Operator* op, TEST(InsertChangesAroundInt32Binops) { TestingGraph t(Type::Signed32(), Type::Signed32()); - Operator* ops[] = {t.machine()->Int32Add(), t.machine()->Int32Sub(), - t.machine()->Int32Mul(), t.machine()->Int32Div(), - t.machine()->Int32Mod(), t.machine()->Word32And(), - t.machine()->Word32Or(), t.machine()->Word32Xor(), - t.machine()->Word32Shl(), t.machine()->Word32Sar()}; + const Operator* ops[] = {t.machine()->Int32Add(), t.machine()->Int32Sub(), + t.machine()->Int32Mul(), t.machine()->Int32Div(), + t.machine()->Int32Mod(), t.machine()->Word32And(), + t.machine()->Word32Or(), t.machine()->Word32Xor(), + t.machine()->Word32Shl(), t.machine()->Word32Sar()}; - for (size_t i = 0; i < ARRAY_SIZE(ops); i++) { + for (size_t i = 0; i < arraysize(ops); i++) { CheckChangesAroundBinop(&t, ops[i], IrOpcode::kChangeTaggedToInt32, IrOpcode::kChangeInt32ToTagged); } @@ -1059,10 +1215,10 @@ TEST(InsertChangesAroundInt32Binops) { TEST(InsertChangesAroundInt32Cmp) { TestingGraph t(Type::Signed32(), Type::Signed32()); - Operator* ops[] = {t.machine()->Int32LessThan(), - t.machine()->Int32LessThanOrEqual()}; + const Operator* ops[] = {t.machine()->Int32LessThan(), + t.machine()->Int32LessThanOrEqual()}; - for (size_t i = 0; i < ARRAY_SIZE(ops); i++) { + for (size_t i = 0; i < arraysize(ops); i++) { CheckChangesAroundBinop(&t, ops[i], IrOpcode::kChangeTaggedToInt32, IrOpcode::kChangeBitToBool); } @@ -1072,10 +1228,10 @@ TEST(InsertChangesAroundInt32Cmp) { TEST(InsertChangesAroundUint32Cmp) { TestingGraph t(Type::Unsigned32(), Type::Unsigned32()); - Operator* ops[] = {t.machine()->Uint32LessThan(), - t.machine()->Uint32LessThanOrEqual()}; + const Operator* ops[] = {t.machine()->Uint32LessThan(), + t.machine()->Uint32LessThanOrEqual()}; - for (size_t i = 0; i < ARRAY_SIZE(ops); i++) { + for (size_t i = 0; i < arraysize(ops); i++) { CheckChangesAroundBinop(&t, ops[i], IrOpcode::kChangeTaggedToUint32, IrOpcode::kChangeBitToBool); } @@ -1085,13 +1241,13 @@ TEST(InsertChangesAroundUint32Cmp) { TEST(InsertChangesAroundFloat64Binops) { TestingGraph t(Type::Number(), Type::Number()); - Operator* ops[] = { + const Operator* ops[] = { t.machine()->Float64Add(), t.machine()->Float64Sub(), t.machine()->Float64Mul(), t.machine()->Float64Div(), t.machine()->Float64Mod(), }; - for (size_t i = 0; i < ARRAY_SIZE(ops); i++) { + for (size_t i = 0; i < arraysize(ops); i++) { CheckChangesAroundBinop(&t, ops[i], IrOpcode::kChangeTaggedToFloat64, IrOpcode::kChangeFloat64ToTagged); } @@ -1101,11 +1257,11 @@ TEST(InsertChangesAroundFloat64Binops) { TEST(InsertChangesAroundFloat64Cmp) { TestingGraph t(Type::Number(), Type::Number()); - Operator* ops[] = {t.machine()->Float64Equal(), - t.machine()->Float64LessThan(), - t.machine()->Float64LessThanOrEqual()}; + const Operator* ops[] = {t.machine()->Float64Equal(), + t.machine()->Float64LessThan(), + t.machine()->Float64LessThanOrEqual()}; - for (size_t i = 0; i < ARRAY_SIZE(ops); i++) { + for (size_t i = 0; i < arraysize(ops); i++) { CheckChangesAroundBinop(&t, ops[i], IrOpcode::kChangeTaggedToFloat64, IrOpcode::kChangeBitToBool); } @@ -1123,28 +1279,7 @@ Node* CheckElementAccessArithmetic(ElementAccess access, Node* load_or_store) { CHECK_EQ(IrOpcode::kInt32Add, index.node()->opcode()); CHECK(index.right().Is(access.header_size - access.tag())); - int element_size = 0; - switch (access.representation) { - case kMachineTagged: - element_size = kPointerSize; - break; - case kMachineWord8: - element_size = 1; - break; - case kMachineWord16: - element_size = 2; - break; - case kMachineWord32: - element_size = 4; - break; - case kMachineWord64: - case kMachineFloat64: - element_size = 8; - break; - case kMachineLast: - UNREACHABLE(); - break; - } + int element_size = ElementSizeOf(access.machine_type); if (element_size != 1) { Int32BinopMatcher mul(index.left().node()); @@ -1157,30 +1292,21 @@ Node* CheckElementAccessArithmetic(ElementAccess access, Node* load_or_store) { } -static const MachineType machine_reps[] = {kMachineWord8, kMachineWord16, - kMachineWord32, kMachineWord64, - kMachineFloat64, kMachineTagged}; - - -// Representation types corresponding to those above. -static const RepType rep_types[] = {static_cast(rWord32 | tUint32), - static_cast(rWord32 | tUint32), - static_cast(rWord32 | tInt32), - static_cast(rWord64), - static_cast(rFloat64 | tNumber), - static_cast(rTagged | tAny)}; +static const MachineType machine_reps[] = { + kRepBit, kMachInt8, kMachInt16, kMachInt32, + kMachInt64, kMachFloat64, kMachAnyTagged}; TEST(LowerLoadField_to_load) { TestingGraph t(Type::Any(), Type::Signed32()); - for (size_t i = 0; i < ARRAY_SIZE(machine_reps); i++) { + for (size_t i = 0; i < arraysize(machine_reps); i++) { FieldAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, Handle::null(), Type::Any(), machine_reps[i]}; Node* load = t.graph()->NewNode(t.simplified()->LoadField(access), t.p0, t.start); - Node* use = t.Use(load, rep_types[i]); + Node* use = t.Use(load, machine_reps[i]); t.Return(use); t.Lower(); CHECK_EQ(IrOpcode::kLoad, load->opcode()); @@ -1196,12 +1322,12 @@ TEST(LowerLoadField_to_load) { TEST(LowerStoreField_to_store) { TestingGraph t(Type::Any(), Type::Signed32()); - for (size_t i = 0; i < ARRAY_SIZE(machine_reps); i++) { + for (size_t i = 0; i < arraysize(machine_reps); i++) { FieldAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, Handle::null(), Type::Any(), machine_reps[i]}; - Node* val = t.ExampleWithOutput(rep_types[i]); + Node* val = t.ExampleWithOutput(machine_reps[i]); Node* store = t.graph()->NewNode(t.simplified()->StoreField(access), t.p0, val, t.start, t.start); t.Effect(store); @@ -1211,10 +1337,10 @@ TEST(LowerStoreField_to_store) { CheckFieldAccessArithmetic(access, store); StoreRepresentation rep = OpParameter(store); - if (rep_types[i] & rTagged) { - CHECK_EQ(kFullWriteBarrier, rep.write_barrier_kind); + if (machine_reps[i] & kRepTagged) { + CHECK_EQ(kFullWriteBarrier, rep.write_barrier_kind()); } - CHECK_EQ(machine_reps[i], rep.rep); + CHECK_EQ(machine_reps[i], rep.machine_type()); } } @@ -1222,13 +1348,14 @@ TEST(LowerStoreField_to_store) { TEST(LowerLoadElement_to_load) { TestingGraph t(Type::Any(), Type::Signed32()); - for (size_t i = 0; i < ARRAY_SIZE(machine_reps); i++) { + for (size_t i = 0; i < arraysize(machine_reps); i++) { ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, Type::Any(), machine_reps[i]}; - Node* load = t.graph()->NewNode(t.simplified()->LoadElement(access), t.p0, - t.p1, t.start); - Node* use = t.Use(load, rep_types[i]); + Node* load = + t.graph()->NewNode(t.simplified()->LoadElement(access), t.p0, t.p1, + t.jsgraph.Int32Constant(1024), t.start); + Node* use = t.Use(load, machine_reps[i]); t.Return(use); t.Lower(); CHECK_EQ(IrOpcode::kLoad, load->opcode()); @@ -1244,13 +1371,14 @@ TEST(LowerLoadElement_to_load) { TEST(LowerStoreElement_to_store) { TestingGraph t(Type::Any(), Type::Signed32()); - for (size_t i = 0; i < ARRAY_SIZE(machine_reps); i++) { + for (size_t i = 0; i < arraysize(machine_reps); i++) { ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, Type::Any(), machine_reps[i]}; - Node* val = t.ExampleWithOutput(rep_types[i]); + Node* val = t.ExampleWithOutput(machine_reps[i]); Node* store = t.graph()->NewNode(t.simplified()->StoreElement(access), t.p0, - t.p1, val, t.start, t.start); + t.p1, t.jsgraph.Int32Constant(1024), val, + t.start, t.start); t.Effect(store); t.Lower(); CHECK_EQ(IrOpcode::kStore, store->opcode()); @@ -1258,23 +1386,23 @@ TEST(LowerStoreElement_to_store) { CheckElementAccessArithmetic(access, store); StoreRepresentation rep = OpParameter(store); - if (rep_types[i] & rTagged) { - CHECK_EQ(kFullWriteBarrier, rep.write_barrier_kind); + if (machine_reps[i] & kRepTagged) { + CHECK_EQ(kFullWriteBarrier, rep.write_barrier_kind()); } - CHECK_EQ(machine_reps[i], rep.rep); + CHECK_EQ(machine_reps[i], rep.machine_type()); } } TEST(InsertChangeForLoadElementIndex) { - // LoadElement(obj: Tagged, index: tInt32 | rTagged) => + // LoadElement(obj: Tagged, index: kTypeInt32 | kRepTagged, length) => // Load(obj, Int32Add(Int32Mul(ChangeTaggedToInt32(index), #k), #k)) - TestingGraph t(Type::Any(), Type::Signed32()); + TestingGraph t(Type::Any(), Type::Signed32(), Type::Any()); ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, Type::Any(), - kMachineTagged}; + kMachAnyTagged}; Node* load = t.graph()->NewNode(t.simplified()->LoadElement(access), t.p0, - t.p1, t.start); + t.p1, t.p2, t.start); t.Return(load); t.Lower(); CHECK_EQ(IrOpcode::kLoad, load->opcode()); @@ -1286,14 +1414,14 @@ TEST(InsertChangeForLoadElementIndex) { TEST(InsertChangeForStoreElementIndex) { - // StoreElement(obj: Tagged, index: tInt32 | rTagged, val) => + // StoreElement(obj: Tagged, index: kTypeInt32 | kRepTagged, length, val) => // Store(obj, Int32Add(Int32Mul(ChangeTaggedToInt32(index), #k), #k), val) - TestingGraph t(Type::Any(), Type::Signed32()); + TestingGraph t(Type::Any(), Type::Signed32(), Type::Any()); ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, Type::Any(), - kMachineTagged}; + kMachAnyTagged}; Node* store = - t.graph()->NewNode(t.simplified()->StoreElement(access), t.p0, t.p1, + t.graph()->NewNode(t.simplified()->StoreElement(access), t.p0, t.p1, t.p2, t.jsgraph.TrueConstant(), t.start, t.start); t.Effect(store); t.Lower(); @@ -1307,12 +1435,12 @@ TEST(InsertChangeForStoreElementIndex) { TEST(InsertChangeForLoadElement) { // TODO(titzer): test all load/store representation change insertions. - TestingGraph t(Type::Any(), Type::Signed32()); + TestingGraph t(Type::Any(), Type::Signed32(), Type::Any()); ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, Type::Any(), - kMachineFloat64}; + kMachFloat64}; Node* load = t.graph()->NewNode(t.simplified()->LoadElement(access), t.p0, - t.p1, t.start); + t.p1, t.p1, t.start); t.Return(load); t.Lower(); CHECK_EQ(IrOpcode::kLoad, load->opcode()); @@ -1325,7 +1453,7 @@ TEST(InsertChangeForLoadField) { // TODO(titzer): test all load/store representation change insertions. TestingGraph t(Type::Any(), Type::Signed32()); FieldAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, - Handle::null(), Type::Any(), kMachineFloat64}; + Handle::null(), Type::Any(), kMachFloat64}; Node* load = t.graph()->NewNode(t.simplified()->LoadField(access), t.p0, t.start); @@ -1339,13 +1467,13 @@ TEST(InsertChangeForLoadField) { TEST(InsertChangeForStoreElement) { // TODO(titzer): test all load/store representation change insertions. - TestingGraph t(Type::Any(), Type::Signed32()); + TestingGraph t(Type::Any(), Type::Signed32(), Type::Any()); ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, Type::Any(), - kMachineFloat64}; + kMachFloat64}; - Node* store = - t.graph()->NewNode(t.simplified()->StoreElement(access), t.p0, - t.jsgraph.Int32Constant(0), t.p1, t.start, t.start); + Node* store = t.graph()->NewNode(t.simplified()->StoreElement(access), t.p0, + t.jsgraph.Int32Constant(0), t.p2, t.p1, + t.start, t.start); t.Effect(store); t.Lower(); @@ -1359,7 +1487,67 @@ TEST(InsertChangeForStoreField) { // TODO(titzer): test all load/store representation change insertions. TestingGraph t(Type::Any(), Type::Signed32()); FieldAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, - Handle::null(), Type::Any(), kMachineFloat64}; + Handle::null(), Type::Any(), kMachFloat64}; + + Node* store = t.graph()->NewNode(t.simplified()->StoreField(access), t.p0, + t.p1, t.start, t.start); + t.Effect(store); + t.Lower(); + + CHECK_EQ(IrOpcode::kStore, store->opcode()); + CHECK_EQ(t.p0, store->InputAt(0)); + CheckChangeOf(IrOpcode::kChangeTaggedToFloat64, t.p1, store->InputAt(2)); +} + + +TEST(UpdatePhi) { + TestingGraph t(Type::Any(), Type::Signed32()); + static const MachineType kMachineTypes[] = {kMachInt32, kMachUint32, + kMachFloat64}; + + for (size_t i = 0; i < arraysize(kMachineTypes); i++) { + FieldAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, + Handle::null(), Type::Any(), kMachineTypes[i]}; + + Node* load0 = + t.graph()->NewNode(t.simplified()->LoadField(access), t.p0, t.start); + Node* load1 = + t.graph()->NewNode(t.simplified()->LoadField(access), t.p1, t.start); + Node* phi = t.graph()->NewNode(t.common()->Phi(kMachAnyTagged, 2), load0, + load1, t.start); + t.Return(t.Use(phi, kMachineTypes[i])); + t.Lower(); + + CHECK_EQ(IrOpcode::kPhi, phi->opcode()); + CHECK_EQ(RepresentationOf(kMachineTypes[i]), + RepresentationOf(OpParameter(phi))); + } +} + + +// TODO(titzer): this tests current behavior of assuming an implicit +// representation change in loading float32s. Fix when float32 is fully +// supported. +TEST(ImplicitFloat32ToFloat64InLoads) { + TestingGraph t(Type::Any()); + + FieldAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, + Handle::null(), Type::Any(), kMachFloat32}; + + Node* load = + t.graph()->NewNode(t.simplified()->LoadField(access), t.p0, t.start); + t.Return(load); + t.Lower(); + CHECK_EQ(IrOpcode::kLoad, load->opcode()); + CHECK_EQ(t.p0, load->InputAt(0)); + CheckChangeOf(IrOpcode::kChangeFloat64ToTagged, load, t.ret->InputAt(0)); +} + + +TEST(ImplicitFloat64ToFloat32InStores) { + TestingGraph t(Type::Any(), Type::Signed32()); + FieldAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, + Handle::null(), Type::Any(), kMachFloat32}; Node* store = t.graph()->NewNode(t.simplified()->StoreField(access), t.p0, t.p1, t.start, t.start);