Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / v8 / test / cctest / compiler / test-simplified-lowering.cc
index 6210198..96fb965 100644 (file)
@@ -4,6 +4,7 @@
 
 #include <limits>
 
+#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 <typename ReturnType>
 class SimplifiedLoweringTester : public GraphBuilderTester<ReturnType> {
  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<ReturnType>(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<ReturnType> {
 };
 
 
-// TODO(dcarney): find a home for these functions.
-namespace {
-
-FieldAccess ForJSObjectMap() {
-  FieldAccess access = {kTaggedBase, JSObject::kMapOffset, Handle<Name>(),
-                        Type::Any(), kMachineTagged};
-  return access;
-}
-
-
-FieldAccess ForJSObjectProperties() {
-  FieldAccess access = {kTaggedBase, JSObject::kPropertiesOffset,
-                        Handle<Name>(), 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<Object*> t;
+  FieldAccess load = {kUntaggedBase, 0, Handle<Name>(), Type::Number(),
+                      kMachFloat64};
+  Node* loaded = t.LoadField(load, t.PointerConstant(&input));
+  Node* convert = t.NumberToInt32(loaded);
+  FieldAccess store = {kUntaggedBase, 0, Handle<Name>(), 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<Name>(),                        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<Object*> t;
+  FieldAccess load = {kUntaggedBase, 0, Handle<Name>(), Type::Number(),
+                      kMachFloat64};
+  Node* loaded = t.LoadField(load, t.PointerConstant(&input));
+  Node* convert = t.NumberToUint32(loaded);
+  FieldAccess store = {kUntaggedBase, 0, Handle<Name>(), 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<int32_t>(expected), static_cast<int32_t>(result));
+    }
+  }
 }
+#endif
 
 
 // Create a simple JSObject with a unique map.
@@ -108,15 +126,15 @@ static Handle<JSObject> TestObject() {
 
 
 TEST(RunLoadMap) {
-  SimplifiedLoweringTester<Object*> t(kMachineTagged);
-  FieldAccess access = ForJSObjectMap();
+  SimplifiedLoweringTester<Object*> 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<JSObject> src = TestObject();
     Handle<Map> src_map(src->map());
     Object* result = t.Call(*src);  // TODO(titzer): raw pointers in call
@@ -126,15 +144,15 @@ TEST(RunLoadMap) {
 
 
 TEST(RunStoreMap) {
-  SimplifiedLoweringTester<int32_t> t(kMachineTagged, kMachineTagged);
-  FieldAccess access = ForJSObjectMap();
+  SimplifiedLoweringTester<int32_t> 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<JSObject> src = TestObject();
     Handle<Map> src_map(src->map());
     Handle<JSObject> dst = TestObject();
@@ -146,15 +164,15 @@ TEST(RunStoreMap) {
 
 
 TEST(RunLoadProperties) {
-  SimplifiedLoweringTester<Object*> t(kMachineTagged);
-  FieldAccess access = ForJSObjectProperties();
+  SimplifiedLoweringTester<Object*> 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<JSObject> src = TestObject();
     Handle<FixedArray> src_props(src->properties());
     Object* result = t.Call(*src);  // TODO(titzer): raw pointers in call
@@ -164,16 +182,16 @@ TEST(RunLoadProperties) {
 
 
 TEST(RunLoadStoreMap) {
-  SimplifiedLoweringTester<Object*> t(kMachineTagged, kMachineTagged);
-  FieldAccess access = ForJSObjectMap();
+  SimplifiedLoweringTester<Object*> 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<JSObject> src = TestObject();
     Handle<Map> src_map(src->map());
     Handle<JSObject> dst = TestObject();
@@ -187,16 +205,18 @@ TEST(RunLoadStoreMap) {
 
 
 TEST(RunLoadStoreFixedArrayIndex) {
-  SimplifiedLoweringTester<Object*> 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<Object*> 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<FixedArray> array = t.factory()->NewFixedArray(2);
     Handle<JSObject> src = TestObject();
     Handle<JSObject> dst = TestObject();
@@ -211,23 +231,25 @@ TEST(RunLoadStoreFixedArrayIndex) {
 
 
 TEST(RunLoadStoreArrayBuffer) {
-  SimplifiedLoweringTester<Object*> t(kMachineTagged);
+  SimplifiedLoweringTester<Object*> 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<JSArrayBuffer> array = t.factory()->NewJSArrayBuffer();
-    const int array_length = 2 * index;
     Runtime::SetupArrayBufferAllocatingData(t.isolate(), array, array_length);
     uint8_t* data = reinterpret_cast<uint8_t*>(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<int>(i * sizeof(Smi*));
     FieldAccess access = {kUntaggedBase, offset, Handle<Name>(),
-                          Type::Integral32(), kMachineTagged};
+                          Type::Integral32(), kMachAnyTagged};
 
     SimplifiedLoweringTester<Object*> 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<int>(i * sizeof(Smi*));
     FieldAccess access = {kUntaggedBase, offset, Handle<Name>(),
-                          Type::Integral32(), kMachineTagged};
+                          Type::Integral32(), kMachAnyTagged};
 
-    SimplifiedLoweringTester<Object*> t(kMachineTagged);
+    SimplifiedLoweringTester<Object*> 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<int>(i * sizeof(Smi*));
       ElementAccess access = {kUntaggedBase, offset, Type::Integral32(),
-                              kMachineTagged};
+                              kMachAnyTagged};
 
       SimplifiedLoweringTester<Object*> t;
-      Node* load = t.LoadElement(access, t.PointerConstant(smis),
-                                 t.Int32Constant(static_cast<int>(j)));
+      Node* load = t.LoadElement(
+          access, t.PointerConstant(smis), t.Int32Constant(static_cast<int>(j)),
+          t.Int32Constant(static_cast<int>(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<int>(i * sizeof(Smi*));
       ElementAccess access = {kUntaggedBase, offset, Type::Integral32(),
-                              kMachineTagged};
+                              kMachAnyTagged};
 
-      SimplifiedLoweringTester<Object*> t(kMachineTagged);
+      SimplifiedLoweringTester<Object*> t(kMachAnyTagged);
       Node* p0 = t.Parameter(0);
       t.StoreElement(access, t.PointerConstant(smis),
-                     t.Int32Constant(static_cast<int>(j)), p0);
+                     t.Int32Constant(static_cast<int>(j)),
+                     t.Int32Constant(static_cast<int>(arraysize(smis))), p0);
       t.Return(p0);
       t.LowerAllNodes();
 
@@ -403,13 +427,15 @@ class AccessTester : public HandleAndZoneScope {
 
     SimplifiedLoweringTester<Object*> 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<int>(num_elements)));
+    t.StoreElement(access, ptr, t.Int32Constant(to_index),
+                   t.Int32Constant(static_cast<int>(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<E>* that) {
+// TODO(titzer): Rewrite this test without StructuredGraphBuilder support.
+#if 0
     SimplifiedLoweringTester<Object*> 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<uint8_t>(kMachineWord8, data, ARRAY_SIZE(data));
+  RunAccessTest<uint8_t>(kMachInt8, data, arraysize(data));
 }
 
 
 TEST(RunAccessTests_uint16) {
   uint16_t data[] = {0x071a, 0x162b, 0x253c, 0x344d, 0x435e, 0x7777};
-  RunAccessTest<uint16_t>(kMachineWord16, data, ARRAY_SIZE(data));
+  RunAccessTest<uint16_t>(kMachInt16, data, arraysize(data));
 }
 
 
 TEST(RunAccessTests_int32) {
   int32_t data[] = {-211, 211, 628347, 2000000000, -2000000000, -1, -100000034};
-  RunAccessTest<int32_t>(kMachineWord32, data, ARRAY_SIZE(data));
+  RunAccessTest<int32_t>(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<int64_t>(kMachineWord64, data, ARRAY_SIZE(data));
+  RunAccessTest<int64_t>(kMachInt64, data, arraysize(data));
 }
 
 
 TEST(RunAccessTests_float64) {
   double data[] = {1.25, -1.25, 2.75, 11.0, 11100.8};
-  RunAccessTest<double>(kMachineFloat64, data, ARRAY_SIZE(data));
+  RunAccessTest<double>(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<Smi*>(kMachineTagged, data, ARRAY_SIZE(data));
+  RunAccessTest<Smi*>(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<IrOpcode::Value>(t.machine()->WordEqual()->opcode());
+    IrOpcode::Value compare_lt =
+        static_cast<IrOpcode::Value>(t.machine()->IntLessThan()->opcode());
+    IrOpcode::Value compare_le = static_cast<IrOpcode::Value>(
+        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<RepType>(rWord32 | tUint32),
-                                    static_cast<RepType>(rWord32 | tUint32),
-                                    static_cast<RepType>(rWord32 | tInt32),
-                                    static_cast<RepType>(rWord64),
-                                    static_cast<RepType>(rFloat64 | tNumber),
-                                    static_cast<RepType>(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<Name>::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<Name>::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<StoreRepresentation>(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<StoreRepresentation>(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<Name>::null(), Type::Any(), kMachineFloat64};
+                        Handle<Name>::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<Name>::null(), Type::Any(), kMachineFloat64};
+                        Handle<Name>::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<Name>::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<MachineType>(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<Name>::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<Name>::null(), Type::Any(), kMachFloat32};
 
   Node* store = t.graph()->NewNode(t.simplified()->StoreField(access), t.p0,
                                    t.p1, t.start, t.start);