Upgrade V8 to version 4.9.385.28

https://chromium.googlesource.com/v8/v8/+/4.9.385.28

FPIIM-449

Change-Id: I4b2e74289d4bf3667f2f3dc8aa2e541f63e26eb4
diff --git a/test/cctest/compiler/c-signature.h b/test/cctest/compiler/c-signature.h
index 5d161db..13ef38a 100644
--- a/test/cctest/compiler/c-signature.h
+++ b/test/cctest/compiler/c-signature.h
@@ -5,86 +5,121 @@
 #ifndef V8_COMPILER_C_SIGNATURE_H_
 #define V8_COMPILER_C_SIGNATURE_H_
 
-#include "src/compiler/machine-type.h"
+#include "src/machine-type.h"
 
 namespace v8 {
 namespace internal {
 namespace compiler {
 
+#define FOREACH_CTYPE_MACHINE_TYPE_MAPPING(V) \
+  V(void, MachineType::None())                \
+  V(bool, MachineType::Uint8())               \
+  V(int8_t, MachineType::Int8())              \
+  V(uint8_t, MachineType::Uint8())            \
+  V(int16_t, MachineType::Int16())            \
+  V(uint16_t, MachineType::Uint16())          \
+  V(int32_t, MachineType::Int32())            \
+  V(uint32_t, MachineType::Uint32())          \
+  V(int64_t, MachineType::Int64())            \
+  V(uint64_t, MachineType::Uint64())          \
+  V(float, MachineType::Float32())            \
+  V(double, MachineType::Float64())           \
+  V(void*, MachineType::Pointer())            \
+  V(int*, MachineType::Pointer())
+
 template <typename T>
 inline MachineType MachineTypeForC() {
-  CHECK(false);  // Instantiated with invalid type.
-  return kMachNone;
+  while (false) {
+    // All other types T must be assignable to Object*
+    *(static_cast<Object* volatile*>(0)) = static_cast<T>(0);
+  }
+  return MachineType::AnyTagged();
 }
 
-template <>
-inline MachineType MachineTypeForC<void>() {
-  return kMachNone;
-}
+#define DECLARE_TEMPLATE_SPECIALIZATION(ctype, mtype) \
+  template <>                                         \
+  inline MachineType MachineTypeForC<ctype>() {       \
+    return mtype;                                     \
+  }
+FOREACH_CTYPE_MACHINE_TYPE_MAPPING(DECLARE_TEMPLATE_SPECIALIZATION)
+#undef DECLARE_TEMPLATE_SPECIALIZATION
 
-template <>
-inline MachineType MachineTypeForC<int8_t>() {
-  return kMachInt8;
-}
+// Helper for building machine signatures from C types.
+class CSignature : public MachineSignature {
+ protected:
+  CSignature(size_t return_count, size_t parameter_count, MachineType* reps)
+      : MachineSignature(return_count, parameter_count, reps) {}
 
-template <>
-inline MachineType MachineTypeForC<uint8_t>() {
-  return kMachUint8;
-}
+ public:
+  template <typename P1 = void, typename P2 = void, typename P3 = void,
+            typename P4 = void, typename P5 = void>
+  void VerifyParams() {
+    // Verifies the C signature against the machine types. Maximum {5} params.
+    CHECK_LT(parameter_count(), 6u);
+    const int kMax = 5;
+    MachineType params[] = {MachineTypeForC<P1>(), MachineTypeForC<P2>(),
+                            MachineTypeForC<P3>(), MachineTypeForC<P4>(),
+                            MachineTypeForC<P5>()};
+    for (int p = kMax - 1; p >= 0; p--) {
+      if (p < static_cast<int>(parameter_count())) {
+        CHECK_EQ(GetParam(p), params[p]);
+      } else {
+        CHECK_EQ(MachineType::None(), params[p]);
+      }
+    }
+  }
 
-template <>
-inline MachineType MachineTypeForC<int16_t>() {
-  return kMachInt16;
-}
+  static CSignature* FromMachine(Zone* zone, MachineSignature* msig) {
+    return reinterpret_cast<CSignature*>(msig);
+  }
 
-template <>
-inline MachineType MachineTypeForC<uint16_t>() {
-  return kMachUint16;
-}
+  static CSignature* New(Zone* zone, MachineType ret,
+                         MachineType p1 = MachineType::None(),
+                         MachineType p2 = MachineType::None(),
+                         MachineType p3 = MachineType::None(),
+                         MachineType p4 = MachineType::None(),
+                         MachineType p5 = MachineType::None()) {
+    MachineType* buffer = zone->NewArray<MachineType>(6);
+    int pos = 0;
+    size_t return_count = 0;
+    if (ret != MachineType::None()) {
+      buffer[pos++] = ret;
+      return_count++;
+    }
+    buffer[pos++] = p1;
+    buffer[pos++] = p2;
+    buffer[pos++] = p3;
+    buffer[pos++] = p4;
+    buffer[pos++] = p5;
+    size_t param_count = 5;
+    if (p5 == MachineType::None()) param_count--;
+    if (p4 == MachineType::None()) param_count--;
+    if (p3 == MachineType::None()) param_count--;
+    if (p2 == MachineType::None()) param_count--;
+    if (p1 == MachineType::None()) param_count--;
+    for (size_t i = 0; i < param_count; i++) {
+      // Check that there are no MachineType::None()'s in the middle of
+      // parameters.
+      CHECK_NE(MachineType::None(), buffer[return_count + i]);
+    }
+    return new (zone) CSignature(return_count, param_count, buffer);
+  }
+};
 
-template <>
-inline MachineType MachineTypeForC<int32_t>() {
-  return kMachInt32;
-}
-
-template <>
-inline MachineType MachineTypeForC<uint32_t>() {
-  return kMachUint32;
-}
-
-template <>
-inline MachineType MachineTypeForC<int64_t>() {
-  return kMachInt64;
-}
-
-template <>
-inline MachineType MachineTypeForC<uint64_t>() {
-  return kMachUint64;
-}
-
-template <>
-inline MachineType MachineTypeForC<double>() {
-  return kMachFloat64;
-}
-
-template <>
-inline MachineType MachineTypeForC<Object*>() {
-  return kMachAnyTagged;
-}
 
 template <typename Ret, uint16_t kParamCount>
-class CSignatureOf : public MachineSignature {
+class CSignatureOf : public CSignature {
  protected:
   MachineType storage_[1 + kParamCount];
 
   CSignatureOf()
-      : MachineSignature(MachineTypeForC<Ret>() != kMachNone ? 1 : 0,
-                         kParamCount,
-                         reinterpret_cast<MachineType*>(&storage_)) {
+      : CSignature(MachineTypeForC<Ret>() != MachineType::None() ? 1 : 0,
+                   kParamCount, reinterpret_cast<MachineType*>(&storage_)) {
     if (return_count_ == 1) storage_[0] = MachineTypeForC<Ret>();
   }
   void Set(int index, MachineType type) {
-    DCHECK(index >= 0 && index < kParamCount);
+    CHECK_LE(0, index);
+    CHECK_LT(index, kParamCount);
     reps_[return_count_ + index] = type;
   }
 };
@@ -123,11 +158,13 @@
   }
 };
 
-static const CSignature2<int32_t, int32_t, int32_t> int32_int32_to_int32;
-static const CSignature2<uint32_t, uint32_t, uint32_t> uint32_uint32_to_uint32;
-static const CSignature2<double, double, double> float64_float64_to_float64;
-}
-}
-}  // namespace v8::internal::compiler
+typedef CSignature2<int32_t, int32_t, int32_t> CSignature_i_ii;
+typedef CSignature2<uint32_t, uint32_t, uint32_t> CSignature_u_uu;
+typedef CSignature2<float, float, float> CSignature_f_ff;
+typedef CSignature2<double, double, double> CSignature_d_dd;
+typedef CSignature2<Object*, Object*, Object*> CSignature_o_oo;
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
 
 #endif  // V8_COMPILER_C_SIGNATURE_H_
diff --git a/test/cctest/compiler/call-tester.h b/test/cctest/compiler/call-tester.h
index cad171e..e60f717 100644
--- a/test/cctest/compiler/call-tester.h
+++ b/test/cctest/compiler/call-tester.h
@@ -5,9 +5,8 @@
 #ifndef V8_CCTEST_COMPILER_CALL_TESTER_H_
 #define V8_CCTEST_COMPILER_CALL_TESTER_H_
 
-#include "src/v8.h"
-
 #include "src/simulator.h"
+#include "test/cctest/compiler/c-signature.h"
 
 #if V8_TARGET_ARCH_IA32
 #if __GNUC__
@@ -23,95 +22,64 @@
 namespace internal {
 namespace compiler {
 
-// TODO(titzer): use c-signature.h instead of ReturnValueTraits
 template <typename R>
-struct ReturnValueTraits {
-  static R Cast(uintptr_t r) { return reinterpret_cast<R>(r); }
-  static MachineType Representation() {
-    // TODO(dcarney): detect when R is of a subclass of Object* instead of this
-    // type check.
-    while (false) {
-      *(static_cast<Object* volatile*>(0)) = static_cast<R>(0);
-    }
-    return kMachAnyTagged;
-  }
-};
+inline R CastReturnValue(uintptr_t r) {
+  return reinterpret_cast<R>(r);
+}
 
 template <>
-struct ReturnValueTraits<int32_t*> {
-  static int32_t* Cast(uintptr_t r) { return reinterpret_cast<int32_t*>(r); }
-  static MachineType Representation() { return kMachPtr; }
-};
+inline void CastReturnValue(uintptr_t r) {}
 
 template <>
-struct ReturnValueTraits<void> {
-  static void Cast(uintptr_t r) {}
-  static MachineType Representation() { return kMachPtr; }
-};
+inline bool CastReturnValue(uintptr_t r) {
+  return static_cast<bool>(r);
+}
 
 template <>
-struct ReturnValueTraits<bool> {
-  static bool Cast(uintptr_t r) { return static_cast<bool>(r); }
-  static MachineType Representation() { return kRepBit; }
-};
+inline int32_t CastReturnValue(uintptr_t r) {
+  return static_cast<int32_t>(r);
+}
 
 template <>
-struct ReturnValueTraits<int32_t> {
-  static int32_t Cast(uintptr_t r) { return static_cast<int32_t>(r); }
-  static MachineType Representation() { return kMachInt32; }
-};
+inline uint32_t CastReturnValue(uintptr_t r) {
+  return static_cast<uint32_t>(r);
+}
 
 template <>
-struct ReturnValueTraits<uint32_t> {
-  static uint32_t Cast(uintptr_t r) { return static_cast<uint32_t>(r); }
-  static MachineType Representation() { return kMachUint32; }
-};
+inline int64_t CastReturnValue(uintptr_t r) {
+  return static_cast<int64_t>(r);
+}
 
 template <>
-struct ReturnValueTraits<int64_t> {
-  static int64_t Cast(uintptr_t r) { return static_cast<int64_t>(r); }
-  static MachineType Representation() { return kMachInt64; }
-};
+inline uint64_t CastReturnValue(uintptr_t r) {
+  return static_cast<uint64_t>(r);
+}
 
 template <>
-struct ReturnValueTraits<uint64_t> {
-  static uint64_t Cast(uintptr_t r) { return static_cast<uint64_t>(r); }
-  static MachineType Representation() { return kMachUint64; }
-};
+inline int16_t CastReturnValue(uintptr_t r) {
+  return static_cast<int16_t>(r);
+}
 
 template <>
-struct ReturnValueTraits<int16_t> {
-  static int16_t Cast(uintptr_t r) { return static_cast<int16_t>(r); }
-  static MachineType Representation() { return kMachInt16; }
-};
+inline uint16_t CastReturnValue(uintptr_t r) {
+  return static_cast<uint16_t>(r);
+}
 
 template <>
-struct ReturnValueTraits<uint16_t> {
-  static uint16_t Cast(uintptr_t r) { return static_cast<uint16_t>(r); }
-  static MachineType Representation() { return kMachUint16; }
-};
+inline int8_t CastReturnValue(uintptr_t r) {
+  return static_cast<int8_t>(r);
+}
 
 template <>
-struct ReturnValueTraits<int8_t> {
-  static int8_t Cast(uintptr_t r) { return static_cast<int8_t>(r); }
-  static MachineType Representation() { return kMachInt8; }
-};
+inline uint8_t CastReturnValue(uintptr_t r) {
+  return static_cast<uint8_t>(r);
+}
 
 template <>
-struct ReturnValueTraits<uint8_t> {
-  static uint8_t Cast(uintptr_t r) { return static_cast<uint8_t>(r); }
-  static MachineType Representation() { return kMachUint8; }
-};
-
-template <>
-struct ReturnValueTraits<double> {
-  static double Cast(uintptr_t r) {
-    UNREACHABLE();
-    return 0.0;
-  }
-  static MachineType Representation() { return kMachFloat64; }
-};
-
+inline double CastReturnValue(uintptr_t r) {
+  UNREACHABLE();
+  return 0.0;
+}
 
 template <typename R>
 struct ParameterTraits {
@@ -128,42 +96,79 @@
   static uintptr_t Cast(void* r) { return reinterpret_cast<uintptr_t>(r); }
 };
 
+
+#if !V8_TARGET_ARCH_32_BIT
+
+// Additional template specialization required for mips64 to sign-extend
+// parameters defined by calling convention.
+template <>
+struct ParameterTraits<int32_t> {
+  static int64_t Cast(int32_t r) { return static_cast<int64_t>(r); }
+};
+
+template <>
+struct ParameterTraits<uint32_t> {
+  static int64_t Cast(uint32_t r) {
+    return static_cast<int64_t>(static_cast<int32_t>(r));
+  }
+};
+
+#endif  // !V8_TARGET_ARCH_64_BIT
+
+
+template <typename R>
 class CallHelper {
  public:
-  explicit CallHelper(Isolate* isolate, MachineSignature* machine_sig)
-      : machine_sig_(machine_sig), isolate_(isolate) {
+  explicit CallHelper(Isolate* isolate, CSignature* csig)
+      : csig_(csig), isolate_(isolate) {
     USE(isolate_);
   }
   virtual ~CallHelper() {}
 
-  static MachineSignature* MakeMachineSignature(
-      Zone* zone, MachineType return_type, MachineType p0 = kMachNone,
-      MachineType p1 = kMachNone, MachineType p2 = kMachNone,
-      MachineType p3 = kMachNone, MachineType p4 = kMachNone) {
-    // Count the number of parameters.
-    size_t param_count = 5;
-    MachineType types[] = {p0, p1, p2, p3, p4};
-    while (param_count > 0 && types[param_count - 1] == kMachNone)
-      param_count--;
-    size_t return_count = return_type == kMachNone ? 0 : 1;
+  R Call() {
+    typedef R V8_CDECL FType();
+    csig_->VerifyParams();
+    return DoCall(FUNCTION_CAST<FType*>(Generate()));
+  }
 
-    // Build the machine signature.
-    MachineSignature::Builder builder(zone, return_count, param_count);
-    if (return_count > 0) builder.AddReturn(return_type);
-    for (size_t i = 0; i < param_count; i++) {
-      builder.AddParam(types[i]);
-    }
-    return builder.Build();
+  template <typename P1>
+  R Call(P1 p1) {
+    typedef R V8_CDECL FType(P1);
+    csig_->VerifyParams<P1>();
+    return DoCall(FUNCTION_CAST<FType*>(Generate()), p1);
+  }
+
+  template <typename P1, typename P2>
+  R Call(P1 p1, P2 p2) {
+    typedef R V8_CDECL FType(P1, P2);
+    csig_->VerifyParams<P1, P2>();
+    return DoCall(FUNCTION_CAST<FType*>(Generate()), p1, p2);
+  }
+
+  template <typename P1, typename P2, typename P3>
+  R Call(P1 p1, P2 p2, P3 p3) {
+    typedef R V8_CDECL FType(P1, P2, P3);
+    csig_->VerifyParams<P1, P2, P3>();
+    return DoCall(FUNCTION_CAST<FType*>(Generate()), p1, p2, p3);
+  }
+
+  template <typename P1, typename P2, typename P3, typename P4>
+  R Call(P1 p1, P2 p2, P3 p3, P4 p4) {
+    typedef R V8_CDECL FType(P1, P2, P3, P4);
+    csig_->VerifyParams<P1, P2, P3, P4>();
+    return DoCall(FUNCTION_CAST<FType*>(Generate()), p1, p2, p3, p4);
+  }
+
+  template <typename P1, typename P2, typename P3, typename P4, typename P5>
+  R Call(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) {
+    typedef R V8_CDECL FType(P1, P2, P3, P4, P5);
+    csig_->VerifyParams<P1, P2, P3, P4, P5>();
+    return DoCall(FUNCTION_CAST<FType*>(Generate()), p1, p2, p3, p4, p5);
   }
 
  protected:
-  MachineSignature* machine_sig_;
-  void VerifyParameters(size_t parameter_count, MachineType* parameter_types) {
-    CHECK(machine_sig_->parameter_count() == parameter_count);
-    for (size_t i = 0; i < parameter_count; i++) {
-      CHECK_EQ(machine_sig_->GetParam(i), parameter_types[i]);
-    }
-  }
+  CSignature* csig_;
+
   virtual byte* Generate() = 0;
 
  private:
@@ -173,255 +178,181 @@
     return static_cast<uintptr_t>(simulator->CallInt64(f, args));
   }
 
-  template <typename R, typename F>
+  template <typename F>
   R DoCall(F* f) {
     Simulator::CallArgument args[] = {Simulator::CallArgument::End()};
-    return ReturnValueTraits<R>::Cast(CallSimulator(FUNCTION_ADDR(f), args));
+    return CastReturnValue<R>(CallSimulator(FUNCTION_ADDR(f), args));
   }
-  template <typename R, typename F, typename P1>
+  template <typename F, typename P1>
   R DoCall(F* f, P1 p1) {
     Simulator::CallArgument args[] = {Simulator::CallArgument(p1),
                                       Simulator::CallArgument::End()};
-    return ReturnValueTraits<R>::Cast(CallSimulator(FUNCTION_ADDR(f), args));
+    return CastReturnValue<R>(CallSimulator(FUNCTION_ADDR(f), args));
   }
-  template <typename R, typename F, typename P1, typename P2>
+  template <typename F, typename P1, typename P2>
   R DoCall(F* f, P1 p1, P2 p2) {
     Simulator::CallArgument args[] = {Simulator::CallArgument(p1),
                                       Simulator::CallArgument(p2),
                                       Simulator::CallArgument::End()};
-    return ReturnValueTraits<R>::Cast(CallSimulator(FUNCTION_ADDR(f), args));
+    return CastReturnValue<R>(CallSimulator(FUNCTION_ADDR(f), args));
   }
-  template <typename R, typename F, typename P1, typename P2, typename P3>
+  template <typename F, typename P1, typename P2, typename P3>
   R DoCall(F* f, P1 p1, P2 p2, P3 p3) {
     Simulator::CallArgument args[] = {
         Simulator::CallArgument(p1), Simulator::CallArgument(p2),
         Simulator::CallArgument(p3), Simulator::CallArgument::End()};
-    return ReturnValueTraits<R>::Cast(CallSimulator(FUNCTION_ADDR(f), args));
+    return CastReturnValue<R>(CallSimulator(FUNCTION_ADDR(f), args));
   }
-  template <typename R, typename F, typename P1, typename P2, typename P3,
-            typename P4>
+  template <typename F, typename P1, typename P2, typename P3, typename P4>
   R DoCall(F* f, P1 p1, P2 p2, P3 p3, P4 p4) {
     Simulator::CallArgument args[] = {
         Simulator::CallArgument(p1), Simulator::CallArgument(p2),
         Simulator::CallArgument(p3), Simulator::CallArgument(p4),
         Simulator::CallArgument::End()};
-    return ReturnValueTraits<R>::Cast(CallSimulator(FUNCTION_ADDR(f), args));
+    return CastReturnValue<R>(CallSimulator(FUNCTION_ADDR(f), args));
   }
-#elif USE_SIMULATOR && V8_TARGET_ARCH_MIPS64
+  template <typename F, typename P1, typename P2, typename P3, typename P4,
+            typename P5>
+  R DoCall(F* f, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) {
+    Simulator::CallArgument args[] = {
+        Simulator::CallArgument(p1), Simulator::CallArgument(p2),
+        Simulator::CallArgument(p3), Simulator::CallArgument(p4),
+        Simulator::CallArgument(p5), Simulator::CallArgument::End()};
+    return CastReturnValue<R>(CallSimulator(FUNCTION_ADDR(f), args));
+  }
+#elif USE_SIMULATOR && (V8_TARGET_ARCH_MIPS64 || V8_TARGET_ARCH_PPC64)
   uintptr_t CallSimulator(byte* f, int64_t p1 = 0, int64_t p2 = 0,
-                          int64_t p3 = 0, int64_t p4 = 0) {
+                          int64_t p3 = 0, int64_t p4 = 0, int64_t p5 = 0) {
     Simulator* simulator = Simulator::current(isolate_);
-    return static_cast<uintptr_t>(simulator->Call(f, 4, p1, p2, p3, p4));
+    return static_cast<uintptr_t>(simulator->Call(f, 5, p1, p2, p3, p4, p5));
   }
 
-  template <typename R, typename F>
+
+  template <typename F>
   R DoCall(F* f) {
-    return ReturnValueTraits<R>::Cast(CallSimulator(FUNCTION_ADDR(f)));
+    return CastReturnValue<R>(CallSimulator(FUNCTION_ADDR(f)));
   }
-  template <typename R, typename F, typename P1>
+  template <typename F, typename P1>
   R DoCall(F* f, P1 p1) {
-    return ReturnValueTraits<R>::Cast(
+    return CastReturnValue<R>(
         CallSimulator(FUNCTION_ADDR(f), ParameterTraits<P1>::Cast(p1)));
   }
-  template <typename R, typename F, typename P1, typename P2>
+  template <typename F, typename P1, typename P2>
   R DoCall(F* f, P1 p1, P2 p2) {
-    return ReturnValueTraits<R>::Cast(
-        CallSimulator(FUNCTION_ADDR(f), ParameterTraits<P1>::Cast(p1),
-                      ParameterTraits<P2>::Cast(p2)));
+    return CastReturnValue<R>(CallSimulator(FUNCTION_ADDR(f),
+                                            ParameterTraits<P1>::Cast(p1),
+                                            ParameterTraits<P2>::Cast(p2)));
   }
-  template <typename R, typename F, typename P1, typename P2, typename P3>
+  template <typename F, typename P1, typename P2, typename P3>
   R DoCall(F* f, P1 p1, P2 p2, P3 p3) {
-    return ReturnValueTraits<R>::Cast(CallSimulator(
+    return CastReturnValue<R>(CallSimulator(
         FUNCTION_ADDR(f), ParameterTraits<P1>::Cast(p1),
         ParameterTraits<P2>::Cast(p2), ParameterTraits<P3>::Cast(p3)));
   }
-  template <typename R, typename F, typename P1, typename P2, typename P3,
-            typename P4>
+  template <typename F, typename P1, typename P2, typename P3, typename P4>
   R DoCall(F* f, P1 p1, P2 p2, P3 p3, P4 p4) {
-    return ReturnValueTraits<R>::Cast(CallSimulator(
+    return CastReturnValue<R>(CallSimulator(
         FUNCTION_ADDR(f), ParameterTraits<P1>::Cast(p1),
         ParameterTraits<P2>::Cast(p2), ParameterTraits<P3>::Cast(p3),
         ParameterTraits<P4>::Cast(p4)));
   }
-#elif USE_SIMULATOR && (V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_MIPS)
+  template <typename F, typename P1, typename P2, typename P3, typename P4,
+            typename P5>
+  R DoCall(F* f, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) {
+    return CastReturnValue<R>(CallSimulator(
+        FUNCTION_ADDR(f), ParameterTraits<P1>::Cast(p1),
+        ParameterTraits<P2>::Cast(p2), ParameterTraits<P3>::Cast(p3),
+        ParameterTraits<P4>::Cast(p4), ParameterTraits<P5>::Cast(p5)));
+  }
+#elif USE_SIMULATOR && \
+    (V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_PPC)
   uintptr_t CallSimulator(byte* f, int32_t p1 = 0, int32_t p2 = 0,
-                          int32_t p3 = 0, int32_t p4 = 0) {
+                          int32_t p3 = 0, int32_t p4 = 0, int32_t p5 = 0) {
     Simulator* simulator = Simulator::current(isolate_);
-    return static_cast<uintptr_t>(simulator->Call(f, 4, p1, p2, p3, p4));
+    return static_cast<uintptr_t>(simulator->Call(f, 5, p1, p2, p3, p4, p5));
   }
-  template <typename R, typename F>
+  template <typename F>
   R DoCall(F* f) {
-    return ReturnValueTraits<R>::Cast(CallSimulator(FUNCTION_ADDR(f)));
+    return CastReturnValue<R>(CallSimulator(FUNCTION_ADDR(f)));
   }
-  template <typename R, typename F, typename P1>
+  template <typename F, typename P1>
   R DoCall(F* f, P1 p1) {
-    return ReturnValueTraits<R>::Cast(
+    return CastReturnValue<R>(
         CallSimulator(FUNCTION_ADDR(f), ParameterTraits<P1>::Cast(p1)));
   }
-  template <typename R, typename F, typename P1, typename P2>
+  template <typename F, typename P1, typename P2>
   R DoCall(F* f, P1 p1, P2 p2) {
-    return ReturnValueTraits<R>::Cast(
-        CallSimulator(FUNCTION_ADDR(f), ParameterTraits<P1>::Cast(p1),
-                      ParameterTraits<P2>::Cast(p2)));
+    return CastReturnValue<R>(CallSimulator(FUNCTION_ADDR(f),
+                                            ParameterTraits<P1>::Cast(p1),
+                                            ParameterTraits<P2>::Cast(p2)));
   }
-  template <typename R, typename F, typename P1, typename P2, typename P3>
+  template <typename F, typename P1, typename P2, typename P3>
   R DoCall(F* f, P1 p1, P2 p2, P3 p3) {
-    return ReturnValueTraits<R>::Cast(CallSimulator(
+    return CastReturnValue<R>(CallSimulator(
         FUNCTION_ADDR(f), ParameterTraits<P1>::Cast(p1),
         ParameterTraits<P2>::Cast(p2), ParameterTraits<P3>::Cast(p3)));
   }
-  template <typename R, typename F, typename P1, typename P2, typename P3,
-            typename P4>
+  template <typename F, typename P1, typename P2, typename P3, typename P4>
   R DoCall(F* f, P1 p1, P2 p2, P3 p3, P4 p4) {
-    return ReturnValueTraits<R>::Cast(CallSimulator(
+    return CastReturnValue<R>(CallSimulator(
         FUNCTION_ADDR(f), ParameterTraits<P1>::Cast(p1),
         ParameterTraits<P2>::Cast(p2), ParameterTraits<P3>::Cast(p3),
         ParameterTraits<P4>::Cast(p4)));
   }
+  template <typename F, typename P1, typename P2, typename P3, typename P4,
+            typename P5>
+  R DoCall(F* f, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) {
+    return CastReturnValue<R>(CallSimulator(
+        FUNCTION_ADDR(f), ParameterTraits<P1>::Cast(p1),
+        ParameterTraits<P2>::Cast(p2), ParameterTraits<P3>::Cast(p3),
+        ParameterTraits<P4>::Cast(p4), ParameterTraits<P5>::Cast(p5)));
+  }
 #else
-  template <typename R, typename F>
+  template <typename F>
   R DoCall(F* f) {
     return f();
   }
-  template <typename R, typename F, typename P1>
+  template <typename F, typename P1>
   R DoCall(F* f, P1 p1) {
     return f(p1);
   }
-  template <typename R, typename F, typename P1, typename P2>
+  template <typename F, typename P1, typename P2>
   R DoCall(F* f, P1 p1, P2 p2) {
     return f(p1, p2);
   }
-  template <typename R, typename F, typename P1, typename P2, typename P3>
+  template <typename F, typename P1, typename P2, typename P3>
   R DoCall(F* f, P1 p1, P2 p2, P3 p3) {
     return f(p1, p2, p3);
   }
-  template <typename R, typename F, typename P1, typename P2, typename P3,
-            typename P4>
+  template <typename F, typename P1, typename P2, typename P3, typename P4>
   R DoCall(F* f, P1 p1, P2 p2, P3 p3, P4 p4) {
     return f(p1, p2, p3, p4);
   }
-#endif
-
-#ifndef DEBUG
-  void VerifyParameters0() {}
-
-  template <typename P1>
-  void VerifyParameters1() {}
-
-  template <typename P1, typename P2>
-  void VerifyParameters2() {}
-
-  template <typename P1, typename P2, typename P3>
-  void VerifyParameters3() {}
-
-  template <typename P1, typename P2, typename P3, typename P4>
-  void VerifyParameters4() {}
-#else
-  void VerifyParameters0() { VerifyParameters(0, NULL); }
-
-  template <typename P1>
-  void VerifyParameters1() {
-    MachineType parameters[] = {ReturnValueTraits<P1>::Representation()};
-    VerifyParameters(arraysize(parameters), parameters);
-  }
-
-  template <typename P1, typename P2>
-  void VerifyParameters2() {
-    MachineType parameters[] = {ReturnValueTraits<P1>::Representation(),
-                                ReturnValueTraits<P2>::Representation()};
-    VerifyParameters(arraysize(parameters), parameters);
-  }
-
-  template <typename P1, typename P2, typename P3>
-  void VerifyParameters3() {
-    MachineType parameters[] = {ReturnValueTraits<P1>::Representation(),
-                                ReturnValueTraits<P2>::Representation(),
-                                ReturnValueTraits<P3>::Representation()};
-    VerifyParameters(arraysize(parameters), parameters);
-  }
-
-  template <typename P1, typename P2, typename P3, typename P4>
-  void VerifyParameters4() {
-    MachineType parameters[] = {ReturnValueTraits<P1>::Representation(),
-                                ReturnValueTraits<P2>::Representation(),
-                                ReturnValueTraits<P3>::Representation(),
-                                ReturnValueTraits<P4>::Representation()};
-    VerifyParameters(arraysize(parameters), parameters);
+  template <typename F, typename P1, typename P2, typename P3, typename P4,
+            typename P5>
+  R DoCall(F* f, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) {
+    return f(p1, p2, p3, p4, p5);
   }
 #endif
 
-  // TODO(dcarney): replace Call() in CallHelper2 with these.
-  template <typename R>
-  R Call0() {
-    typedef R V8_CDECL FType();
-    VerifyParameters0();
-    return DoCall<R>(FUNCTION_CAST<FType*>(Generate()));
-  }
-
-  template <typename R, typename P1>
-  R Call1(P1 p1) {
-    typedef R V8_CDECL FType(P1);
-    VerifyParameters1<P1>();
-    return DoCall<R>(FUNCTION_CAST<FType*>(Generate()), p1);
-  }
-
-  template <typename R, typename P1, typename P2>
-  R Call2(P1 p1, P2 p2) {
-    typedef R V8_CDECL FType(P1, P2);
-    VerifyParameters2<P1, P2>();
-    return DoCall<R>(FUNCTION_CAST<FType*>(Generate()), p1, p2);
-  }
-
-  template <typename R, typename P1, typename P2, typename P3>
-  R Call3(P1 p1, P2 p2, P3 p3) {
-    typedef R V8_CDECL FType(P1, P2, P3);
-    VerifyParameters3<P1, P2, P3>();
-    return DoCall<R>(FUNCTION_CAST<FType*>(Generate()), p1, p2, p3);
-  }
-
-  template <typename R, typename P1, typename P2, typename P3, typename P4>
-  R Call4(P1 p1, P2 p2, P3 p3, P4 p4) {
-    typedef R V8_CDECL FType(P1, P2, P3, P4);
-    VerifyParameters4<P1, P2, P3, P4>();
-    return DoCall<R>(FUNCTION_CAST<FType*>(Generate()), p1, p2, p3, p4);
-  }
-
-  template <typename R, typename C>
-  friend class CallHelper2;
   Isolate* isolate_;
 };
 
-
-// TODO(dcarney): replace CallHelper with CallHelper2 and rename.
-template <typename R, typename C>
-class CallHelper2 {
+// A call helper that calls the given code object assuming C calling convention.
+template <typename T>
+class CodeRunner : public CallHelper<T> {
  public:
-  R Call() { return helper()->template Call0<R>(); }
+  CodeRunner(Isolate* isolate, Handle<Code> code, CSignature* csig)
+      : CallHelper<T>(isolate, csig), code_(code) {}
+  virtual ~CodeRunner() {}
 
-  template <typename P1>
-  R Call(P1 p1) {
-    return helper()->template Call1<R>(p1);
-  }
-
-  template <typename P1, typename P2>
-  R Call(P1 p1, P2 p2) {
-    return helper()->template Call2<R>(p1, p2);
-  }
-
-  template <typename P1, typename P2, typename P3>
-  R Call(P1 p1, P2 p2, P3 p3) {
-    return helper()->template Call3<R>(p1, p2, p3);
-  }
-
-  template <typename P1, typename P2, typename P3, typename P4>
-  R Call(P1 p1, P2 p2, P3 p3, P4 p4) {
-    return helper()->template Call4<R>(p1, p2, p3, p4);
-  }
+  virtual byte* Generate() { return code_->entry(); }
 
  private:
-  CallHelper* helper() { return static_cast<C*>(this); }
+  Handle<Code> code_;
 };
 
+
 }  // namespace compiler
 }  // namespace internal
 }  // namespace v8
diff --git a/test/cctest/compiler/codegen-tester.cc b/test/cctest/compiler/codegen-tester.cc
index 5311001..fc0956f 100644
--- a/test/cctest/compiler/codegen-tester.cc
+++ b/test/cctest/compiler/codegen-tester.cc
@@ -2,14 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "src/v8.h"
-
 #include "test/cctest/cctest.h"
 #include "test/cctest/compiler/codegen-tester.h"
 #include "test/cctest/compiler/value-helper.h"
 
-using namespace v8::internal;
-using namespace v8::internal::compiler;
+namespace v8 {
+namespace internal {
+namespace compiler {
 
 TEST(CompareWrapper) {
   // Who tests the testers?
@@ -141,7 +140,7 @@
   CompareWrapper wFloat64LessThanOrEqual(IrOpcode::kFloat64LessThanOrEqual);
 
   // Check NaN handling.
-  double nan = v8::base::OS::nan_value();
+  double nan = std::numeric_limits<double>::quiet_NaN();
   double inf = V8_INFINITY;
   CHECK_EQ(false, wFloat64Equal.Float64Compare(nan, 0.0));
   CHECK_EQ(false, wFloat64Equal.Float64Compare(nan, 1.0));
@@ -292,7 +291,8 @@
   for (int i = -2; i < num_int_inputs; i++) {    // for all left shapes
     for (int j = -2; j < num_int_inputs; j++) {  // for all right shapes
       if (i >= 0 && j >= 0) break;               // No constant/constant combos
-      RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32);
+      RawMachineAssemblerTester<int32_t> m(MachineType::Int32(),
+                                           MachineType::Int32());
       Node* p0 = m.Parameter(0);
       Node* p1 = m.Parameter(1);
       Node* n0;
@@ -302,7 +302,7 @@
       if (i == -2) {
         n0 = p0;
       } else if (i == -1) {
-        n0 = m.LoadFromPointer(&input_a, kMachInt32);
+        n0 = m.LoadFromPointer(&input_a, MachineType::Int32());
       } else {
         n0 = m.Int32Constant(inputs[i]);
       }
@@ -311,7 +311,7 @@
       if (j == -2) {
         n1 = p1;
       } else if (j == -1) {
-        n1 = m.LoadFromPointer(&input_b, kMachInt32);
+        n1 = m.LoadFromPointer(&input_b, MachineType::Int32());
       } else {
         n1 = m.Int32Constant(inputs[j]);
       }
@@ -368,14 +368,13 @@
 }
 
 
-#if V8_TURBOFAN_TARGET
-
 TEST(ParametersEqual) {
-  RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32);
+  RawMachineAssemblerTester<int32_t> m(MachineType::Int32(),
+                                       MachineType::Int32());
   Node* p1 = m.Parameter(1);
-  CHECK_NE(NULL, p1);
+  CHECK(p1);
   Node* p0 = m.Parameter(0);
-  CHECK_NE(NULL, p0);
+  CHECK(p0);
   CHECK_EQ(p0, m.Parameter(0));
   CHECK_EQ(p1, m.Parameter(1));
 }
@@ -485,7 +484,7 @@
 
 
 TEST(RunParam1) {
-  RawMachineAssemblerTester<int32_t> m(kMachInt32);
+  RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
   m.Return(m.Parameter(0));
 
   FOR_INT32_INPUTS(i) {
@@ -496,7 +495,8 @@
 
 
 TEST(RunParam2_1) {
-  RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32);
+  RawMachineAssemblerTester<int32_t> m(MachineType::Int32(),
+                                       MachineType::Int32());
   Node* p0 = m.Parameter(0);
   Node* p1 = m.Parameter(1);
   m.Return(p0);
@@ -510,7 +510,8 @@
 
 
 TEST(RunParam2_2) {
-  RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32);
+  RawMachineAssemblerTester<int32_t> m(MachineType::Int32(),
+                                       MachineType::Int32());
   Node* p0 = m.Parameter(0);
   Node* p1 = m.Parameter(1);
   m.Return(p1);
@@ -525,7 +526,8 @@
 
 TEST(RunParam3) {
   for (int i = 0; i < 3; i++) {
-    RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32, kMachInt32);
+    RawMachineAssemblerTester<int32_t> m(
+        MachineType::Int32(), MachineType::Int32(), MachineType::Int32());
     Node* nodes[] = {m.Parameter(0), m.Parameter(1), m.Parameter(2)};
     m.Return(nodes[i]);
 
@@ -561,7 +563,7 @@
     Float64BinopTester bt(&m);
     bt.AddReturn(bt.param0);
 
-    FOR_FLOAT64_INPUTS(i) { CHECK_EQ(*i, bt.call(*i, 9.0)); }
+    FOR_FLOAT64_INPUTS(i) { CheckDoubleEq(*i, bt.call(*i, 9.0)); }
   }
 
   {
@@ -569,8 +571,156 @@
     Float64BinopTester bt(&m);
     bt.AddReturn(bt.param1);
 
-    FOR_FLOAT64_INPUTS(i) { CHECK_EQ(*i, bt.call(-11.25, *i)); }
+    FOR_FLOAT64_INPUTS(i) { CheckDoubleEq(*i, bt.call(-11.25, *i)); }
   }
 }
 
-#endif  // V8_TURBOFAN_TARGET
+
+#if V8_TARGET_ARCH_64_BIT
+// TODO(ahaas): run int64 tests on all platforms when supported.
+TEST(RunBufferedRawMachineAssemblerTesterTester) {
+  {
+    BufferedRawMachineAssemblerTester<int64_t> m;
+    m.Return(m.Int64Constant(0x12500000000));
+    CHECK_EQ(0x12500000000, m.Call());
+  }
+  {
+    BufferedRawMachineAssemblerTester<double> m(MachineType::Float64());
+    m.Return(m.Parameter(0));
+    FOR_FLOAT64_INPUTS(i) { CheckDoubleEq(*i, m.Call(*i)); }
+  }
+  {
+    BufferedRawMachineAssemblerTester<int64_t> m(MachineType::Int64(),
+                                                 MachineType::Int64());
+    m.Return(m.Int64Add(m.Parameter(0), m.Parameter(1)));
+    FOR_INT64_INPUTS(i) {
+      FOR_INT64_INPUTS(j) {
+        CHECK_EQ(*i + *j, m.Call(*i, *j));
+        CHECK_EQ(*j + *i, m.Call(*j, *i));
+      }
+    }
+  }
+  {
+    BufferedRawMachineAssemblerTester<int64_t> m(
+        MachineType::Int64(), MachineType::Int64(), MachineType::Int64());
+    m.Return(
+        m.Int64Add(m.Int64Add(m.Parameter(0), m.Parameter(1)), m.Parameter(2)));
+    FOR_INT64_INPUTS(i) {
+      FOR_INT64_INPUTS(j) {
+        CHECK_EQ(*i + *i + *j, m.Call(*i, *i, *j));
+        CHECK_EQ(*i + *j + *i, m.Call(*i, *j, *i));
+        CHECK_EQ(*j + *i + *i, m.Call(*j, *i, *i));
+      }
+    }
+  }
+  {
+    BufferedRawMachineAssemblerTester<int64_t> m(
+        MachineType::Int64(), MachineType::Int64(), MachineType::Int64(),
+        MachineType::Int64());
+    m.Return(m.Int64Add(
+        m.Int64Add(m.Int64Add(m.Parameter(0), m.Parameter(1)), m.Parameter(2)),
+        m.Parameter(3)));
+    FOR_INT64_INPUTS(i) {
+      FOR_INT64_INPUTS(j) {
+        CHECK_EQ(*i + *i + *i + *j, m.Call(*i, *i, *i, *j));
+        CHECK_EQ(*i + *i + *j + *i, m.Call(*i, *i, *j, *i));
+        CHECK_EQ(*i + *j + *i + *i, m.Call(*i, *j, *i, *i));
+        CHECK_EQ(*j + *i + *i + *i, m.Call(*j, *i, *i, *i));
+      }
+    }
+  }
+  {
+    BufferedRawMachineAssemblerTester<void> m;
+    int64_t result;
+    m.Store(MachineTypeForC<int64_t>().representation(),
+            m.PointerConstant(&result), m.Int64Constant(0x12500000000),
+            kNoWriteBarrier);
+    m.Return(m.Int32Constant(0));
+    m.Call();
+    CHECK_EQ(0x12500000000, result);
+  }
+  {
+    BufferedRawMachineAssemblerTester<void> m(MachineType::Float64());
+    double result;
+    m.Store(MachineTypeForC<double>().representation(),
+            m.PointerConstant(&result), m.Parameter(0), kNoWriteBarrier);
+    m.Return(m.Int32Constant(0));
+    FOR_FLOAT64_INPUTS(i) {
+      m.Call(*i);
+      CheckDoubleEq(*i, result);
+    }
+  }
+  {
+    BufferedRawMachineAssemblerTester<void> m(MachineType::Int64(),
+                                              MachineType::Int64());
+    int64_t result;
+    m.Store(MachineTypeForC<int64_t>().representation(),
+            m.PointerConstant(&result),
+            m.Int64Add(m.Parameter(0), m.Parameter(1)), kNoWriteBarrier);
+    m.Return(m.Int32Constant(0));
+    FOR_INT64_INPUTS(i) {
+      FOR_INT64_INPUTS(j) {
+        m.Call(*i, *j);
+        CHECK_EQ(*i + *j, result);
+
+        m.Call(*j, *i);
+        CHECK_EQ(*j + *i, result);
+      }
+    }
+  }
+  {
+    BufferedRawMachineAssemblerTester<void> m(
+        MachineType::Int64(), MachineType::Int64(), MachineType::Int64());
+    int64_t result;
+    m.Store(
+        MachineTypeForC<int64_t>().representation(), m.PointerConstant(&result),
+        m.Int64Add(m.Int64Add(m.Parameter(0), m.Parameter(1)), m.Parameter(2)),
+        kNoWriteBarrier);
+    m.Return(m.Int32Constant(0));
+    FOR_INT64_INPUTS(i) {
+      FOR_INT64_INPUTS(j) {
+        m.Call(*i, *i, *j);
+        CHECK_EQ(*i + *i + *j, result);
+
+        m.Call(*i, *j, *i);
+        CHECK_EQ(*i + *j + *i, result);
+
+        m.Call(*j, *i, *i);
+        CHECK_EQ(*j + *i + *i, result);
+      }
+    }
+  }
+  {
+    BufferedRawMachineAssemblerTester<void> m(
+        MachineType::Int64(), MachineType::Int64(), MachineType::Int64(),
+        MachineType::Int64());
+    int64_t result;
+    m.Store(MachineTypeForC<int64_t>().representation(),
+            m.PointerConstant(&result),
+            m.Int64Add(m.Int64Add(m.Int64Add(m.Parameter(0), m.Parameter(1)),
+                                  m.Parameter(2)),
+                       m.Parameter(3)),
+            kNoWriteBarrier);
+    m.Return(m.Int32Constant(0));
+    FOR_INT64_INPUTS(i) {
+      FOR_INT64_INPUTS(j) {
+        m.Call(*i, *i, *i, *j);
+        CHECK_EQ(*i + *i + *i + *j, result);
+
+        m.Call(*i, *i, *j, *i);
+        CHECK_EQ(*i + *i + *j + *i, result);
+
+        m.Call(*i, *j, *i, *i);
+        CHECK_EQ(*i + *j + *i + *i, result);
+
+        m.Call(*j, *i, *i, *i);
+        CHECK_EQ(*j + *i + *i + *i, result);
+      }
+    }
+  }
+}
+
+#endif
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/test/cctest/compiler/codegen-tester.h b/test/cctest/compiler/codegen-tester.h
index 283d533..56e90c6 100644
--- a/test/cctest/compiler/codegen-tester.h
+++ b/test/cctest/compiler/codegen-tester.h
@@ -5,8 +5,6 @@
 #ifndef V8_CCTEST_COMPILER_CODEGEN_TESTER_H_
 #define V8_CCTEST_COMPILER_CODEGEN_TESTER_H_
 
-#include "src/v8.h"
-
 #include "src/compiler/instruction-selector.h"
 #include "src/compiler/pipeline.h"
 #include "src/compiler/raw-machine-assembler.h"
@@ -17,38 +15,29 @@
 namespace internal {
 namespace compiler {
 
-template <typename MachineAssembler>
-class MachineAssemblerTester : public HandleAndZoneScope,
-                               public CallHelper,
-                               public MachineAssembler {
+template <typename ReturnType>
+class RawMachineAssemblerTester : public HandleAndZoneScope,
+                                  public CallHelper<ReturnType>,
+                                  public RawMachineAssembler {
  public:
-  MachineAssemblerTester(MachineType return_type, MachineType p0,
-                         MachineType p1, MachineType p2, MachineType p3,
-                         MachineType p4,
-                         MachineOperatorBuilder::Flags flags =
-                             MachineOperatorBuilder::Flag::kNoFlags)
+  RawMachineAssemblerTester(MachineType p0 = MachineType::None(),
+                            MachineType p1 = MachineType::None(),
+                            MachineType p2 = MachineType::None(),
+                            MachineType p3 = MachineType::None(),
+                            MachineType p4 = MachineType::None())
       : HandleAndZoneScope(),
-        CallHelper(
+        CallHelper<ReturnType>(
             main_isolate(),
-            MakeMachineSignature(main_zone(), return_type, p0, p1, p2, p3, p4)),
-        MachineAssembler(
-            new (main_zone()) Graph(main_zone()),
-            MakeMachineSignature(main_zone(), return_type, p0, p1, p2, p3, p4),
-            kMachPtr, flags) {}
-
-  Node* LoadFromPointer(void* address, MachineType rep, int32_t offset = 0) {
-    return this->Load(rep, this->PointerConstant(address),
-                      this->Int32Constant(offset));
-  }
-
-  void StoreToPointer(void* address, MachineType rep, Node* node) {
-    this->Store(rep, this->PointerConstant(address), node);
-  }
-
-  Node* StringConstant(const char* string) {
-    return this->HeapConstant(
-        this->isolate()->factory()->InternalizeUtf8String(string));
-  }
+            CSignature::New(main_zone(), MachineTypeForC<ReturnType>(), p0, p1,
+                            p2, p3, p4)),
+        RawMachineAssembler(
+            main_isolate(), new (main_zone()) Graph(main_zone()),
+            Linkage::GetSimplifiedCDescriptor(
+                main_zone(),
+                CSignature::New(main_zone(), MachineTypeForC<ReturnType>(), p0,
+                                p1, p2, p3, p4)),
+            MachineType::PointerRepresentation(),
+            InstructionSelector::SupportedMachineOperatorFlags()) {}
 
   void CheckNumber(double expected, Object* number) {
     CHECK(this->isolate()->factory()->NewNumber(expected)->SameValue(number));
@@ -62,14 +51,20 @@
 
   void GenerateCode() { Generate(); }
 
+  Handle<Code> GetCode() {
+    Generate();
+    return code_.ToHandleChecked();
+  }
+
  protected:
   virtual byte* Generate() {
     if (code_.is_null()) {
       Schedule* schedule = this->Export();
       CallDescriptor* call_descriptor = this->call_descriptor();
       Graph* graph = this->graph();
-      code_ =
-          Pipeline::GenerateCodeForTesting(call_descriptor, graph, schedule);
+      CompilationInfo info("testing", main_isolate(), main_zone());
+      code_ = Pipeline::GenerateCodeForTesting(&info, call_descriptor, graph,
+                                               schedule);
     }
     return this->code_.ToHandleChecked()->entry();
   }
@@ -80,40 +75,226 @@
 
 
 template <typename ReturnType>
-class RawMachineAssemblerTester
-    : public MachineAssemblerTester<RawMachineAssembler>,
-      public CallHelper2<ReturnType, RawMachineAssemblerTester<ReturnType> > {
+class BufferedRawMachineAssemblerTester
+    : public RawMachineAssemblerTester<int32_t> {
  public:
-  RawMachineAssemblerTester(MachineType p0 = kMachNone,
-                            MachineType p1 = kMachNone,
-                            MachineType p2 = kMachNone,
-                            MachineType p3 = kMachNone,
-                            MachineType p4 = kMachNone)
-      : MachineAssemblerTester<RawMachineAssembler>(
-            ReturnValueTraits<ReturnType>::Representation(), p0, p1, p2, p3, p4,
-            InstructionSelector::SupportedMachineOperatorFlags()) {}
+  BufferedRawMachineAssemblerTester(MachineType p0 = MachineType::None(),
+                                    MachineType p1 = MachineType::None(),
+                                    MachineType p2 = MachineType::None(),
+                                    MachineType p3 = MachineType::None())
+      : BufferedRawMachineAssemblerTester(ComputeParameterCount(p0, p1, p2, p3),
+                                          p0, p1, p2, p3) {}
 
-  template <typename Ci, typename Fn>
-  void Run(const Ci& ci, const Fn& fn) {
-    typename Ci::const_iterator i;
-    for (i = ci.begin(); i != ci.end(); ++i) {
-      CHECK_EQ(fn(*i), this->Call(*i));
-    }
+
+  // The BufferedRawMachineAssemblerTester does not pass parameters directly
+  // to the constructed IR graph. Instead it passes a pointer to the parameter
+  // to the IR graph, and adds Load nodes to the IR graph to load the
+  // parameters from memory. Thereby it is possible to pass 64 bit parameters
+  // to the IR graph.
+  Node* Parameter(size_t index) {
+    CHECK(index >= 0 && index < 4);
+    return parameter_nodes_[index];
   }
 
-  template <typename Ci, typename Cj, typename Fn>
-  void Run(const Ci& ci, const Cj& cj, const Fn& fn) {
-    typename Ci::const_iterator i;
-    typename Cj::const_iterator j;
-    for (i = ci.begin(); i != ci.end(); ++i) {
-      for (j = cj.begin(); j != cj.end(); ++j) {
-        CHECK_EQ(fn(*i, *j), this->Call(*i, *j));
-      }
-    }
+
+  // The BufferedRawMachineAssemblerTester adds a Store node to the IR graph
+  // to store the graph's return value in memory. The memory address for the
+  // Store node is provided as a parameter. By storing the return value in
+  // memory it is possible to return 64 bit values.
+  void Return(Node* input) {
+    Store(MachineTypeForC<ReturnType>().representation(),
+          RawMachineAssembler::Parameter(return_parameter_index_), input,
+          kNoWriteBarrier);
+    RawMachineAssembler::Return(Int32Constant(1234));
   }
+
+  ReturnType Call() {
+    ReturnType return_value;
+    test_graph_signature_->VerifyParams();
+    CallHelper<int32_t>::Call(reinterpret_cast<void*>(&return_value));
+    return return_value;
+  }
+
+  template <typename P0>
+  ReturnType Call(P0 p0) {
+    ReturnType return_value;
+    test_graph_signature_->VerifyParams<P0>();
+    CallHelper<int32_t>::Call(reinterpret_cast<void*>(&p0),
+                              reinterpret_cast<void*>(&return_value));
+    return return_value;
+  }
+
+  template <typename P0, typename P1>
+  ReturnType Call(P0 p0, P1 p1) {
+    ReturnType return_value;
+    test_graph_signature_->VerifyParams<P0, P1>();
+    CallHelper<int32_t>::Call(reinterpret_cast<void*>(&p0),
+                              reinterpret_cast<void*>(&p1),
+                              reinterpret_cast<void*>(&return_value));
+    return return_value;
+  }
+
+  template <typename P0, typename P1, typename P2>
+  ReturnType Call(P0 p0, P1 p1, P2 p2) {
+    ReturnType return_value;
+    test_graph_signature_->VerifyParams<P0, P1, P2>();
+    CallHelper<int32_t>::Call(
+        reinterpret_cast<void*>(&p0), reinterpret_cast<void*>(&p1),
+        reinterpret_cast<void*>(&p2), reinterpret_cast<void*>(&return_value));
+    return return_value;
+  }
+
+  template <typename P0, typename P1, typename P2, typename P3>
+  ReturnType Call(P0 p0, P1 p1, P2 p2, P3 p3) {
+    ReturnType return_value;
+    test_graph_signature_->VerifyParams<P0, P1, P2, P3>();
+    CallHelper<int32_t>::Call(
+        reinterpret_cast<void*>(&p0), reinterpret_cast<void*>(&p1),
+        reinterpret_cast<void*>(&p2), reinterpret_cast<void*>(&p3),
+        reinterpret_cast<void*>(&return_value));
+    return return_value;
+  }
+
+ private:
+  BufferedRawMachineAssemblerTester(uint32_t return_parameter_index,
+                                    MachineType p0, MachineType p1,
+                                    MachineType p2, MachineType p3)
+      : RawMachineAssemblerTester<int32_t>(
+            MachineType::Pointer(),
+            p0 == MachineType::None() ? MachineType::None()
+                                      : MachineType::Pointer(),
+            p1 == MachineType::None() ? MachineType::None()
+                                      : MachineType::Pointer(),
+            p2 == MachineType::None() ? MachineType::None()
+                                      : MachineType::Pointer(),
+            p3 == MachineType::None() ? MachineType::None()
+                                      : MachineType::Pointer()),
+        test_graph_signature_(
+            CSignature::New(main_zone(), MachineType::Int32(), p0, p1, p2, p3)),
+        return_parameter_index_(return_parameter_index) {
+    parameter_nodes_[0] = p0 == MachineType::None()
+                              ? nullptr
+                              : Load(p0, RawMachineAssembler::Parameter(0));
+    parameter_nodes_[1] = p1 == MachineType::None()
+                              ? nullptr
+                              : Load(p1, RawMachineAssembler::Parameter(1));
+    parameter_nodes_[2] = p2 == MachineType::None()
+                              ? nullptr
+                              : Load(p2, RawMachineAssembler::Parameter(2));
+    parameter_nodes_[3] = p3 == MachineType::None()
+                              ? nullptr
+                              : Load(p3, RawMachineAssembler::Parameter(3));
+  }
+
+
+  static uint32_t ComputeParameterCount(MachineType p0, MachineType p1,
+                                        MachineType p2, MachineType p3) {
+    if (p0 == MachineType::None()) {
+      return 0;
+    }
+    if (p1 == MachineType::None()) {
+      return 1;
+    }
+    if (p2 == MachineType::None()) {
+      return 2;
+    }
+    if (p3 == MachineType::None()) {
+      return 3;
+    }
+    return 4;
+  }
+
+
+  CSignature* test_graph_signature_;
+  Node* parameter_nodes_[4];
+  uint32_t return_parameter_index_;
 };
 
 
+template <>
+class BufferedRawMachineAssemblerTester<void>
+    : public RawMachineAssemblerTester<void> {
+ public:
+  BufferedRawMachineAssemblerTester(MachineType p0 = MachineType::None(),
+                                    MachineType p1 = MachineType::None(),
+                                    MachineType p2 = MachineType::None(),
+                                    MachineType p3 = MachineType::None())
+      : RawMachineAssemblerTester<void>(
+            p0 == MachineType::None() ? MachineType::None()
+                                      : MachineType::Pointer(),
+            p1 == MachineType::None() ? MachineType::None()
+                                      : MachineType::Pointer(),
+            p2 == MachineType::None() ? MachineType::None()
+                                      : MachineType::Pointer(),
+            p3 == MachineType::None() ? MachineType::None()
+                                      : MachineType::Pointer()),
+        test_graph_signature_(
+            CSignature::New(RawMachineAssemblerTester<void>::main_zone(),
+                            MachineType::None(), p0, p1, p2, p3)) {
+    parameter_nodes_[0] = p0 == MachineType::None()
+                              ? nullptr
+                              : Load(p0, RawMachineAssembler::Parameter(0));
+    parameter_nodes_[1] = p1 == MachineType::None()
+                              ? nullptr
+                              : Load(p1, RawMachineAssembler::Parameter(1));
+    parameter_nodes_[2] = p2 == MachineType::None()
+                              ? nullptr
+                              : Load(p2, RawMachineAssembler::Parameter(2));
+    parameter_nodes_[3] = p3 == MachineType::None()
+                              ? nullptr
+                              : Load(p3, RawMachineAssembler::Parameter(3));
+  }
+
+
+  // The BufferedRawMachineAssemblerTester does not pass parameters directly
+  // to the constructed IR graph. Instead it passes a pointer to the parameter
+  // to the IR graph, and adds Load nodes to the IR graph to load the
+  // parameters from memory. Thereby it is possible to pass 64 bit parameters
+  // to the IR graph.
+  Node* Parameter(size_t index) {
+    CHECK(index >= 0 && index < 4);
+    return parameter_nodes_[index];
+  }
+
+
+  void Call() {
+    test_graph_signature_->VerifyParams();
+    CallHelper<void>::Call();
+  }
+
+  template <typename P0>
+  void Call(P0 p0) {
+    test_graph_signature_->VerifyParams<P0>();
+    CallHelper<void>::Call(reinterpret_cast<void*>(&p0));
+  }
+
+  template <typename P0, typename P1>
+  void Call(P0 p0, P1 p1) {
+    test_graph_signature_->VerifyParams<P0, P1>();
+    CallHelper<void>::Call(reinterpret_cast<void*>(&p0),
+                           reinterpret_cast<void*>(&p1));
+  }
+
+  template <typename P0, typename P1, typename P2>
+  void Call(P0 p0, P1 p1, P2 p2) {
+    test_graph_signature_->VerifyParams<P0, P1, P2>();
+    CallHelper<void>::Call(reinterpret_cast<void*>(&p0),
+                           reinterpret_cast<void*>(&p1),
+                           reinterpret_cast<void*>(&p2));
+  }
+
+  template <typename P0, typename P1, typename P2, typename P3>
+  void Call(P0 p0, P1 p1, P2 p2, P3 p3) {
+    test_graph_signature_->VerifyParams<P0, P1, P2, P3>();
+    CallHelper<void>::Call(
+        reinterpret_cast<void*>(&p0), reinterpret_cast<void*>(&p1),
+        reinterpret_cast<void*>(&p2), reinterpret_cast<void*>(&p3));
+  }
+
+ private:
+  CSignature* test_graph_signature_;
+  Node* parameter_nodes_[4];
+};
 static const bool USE_RESULT_BUFFER = true;
 static const bool USE_RETURN_REGISTER = false;
 static const int32_t CHECK_VALUE = 0x99BEEDCE;
@@ -121,13 +302,15 @@
 
 // TODO(titzer): use the C-style calling convention, or any register-based
 // calling convention for binop tests.
-template <typename CType, MachineType rep, bool use_result_buffer>
+template <typename CType, bool use_result_buffer>
 class BinopTester {
  public:
-  explicit BinopTester(RawMachineAssemblerTester<int32_t>* tester)
+  explicit BinopTester(RawMachineAssemblerTester<int32_t>* tester,
+                       MachineType rep)
       : T(tester),
         param0(T->LoadFromPointer(&p0, rep)),
         param1(T->LoadFromPointer(&p1, rep)),
+        rep(rep),
         p0(static_cast<CType>(0)),
         p1(static_cast<CType>(0)),
         result(static_cast<CType>(0)) {}
@@ -143,13 +326,14 @@
       CHECK_EQ(CHECK_VALUE, T->Call());
       return result;
     } else {
-      return T->Call();
+      return static_cast<CType>(T->Call());
     }
   }
 
   void AddReturn(Node* val) {
     if (use_result_buffer) {
-      T->Store(rep, T->PointerConstant(&result), T->Int32Constant(0), val);
+      T->Store(rep.representation(), T->PointerConstant(&result),
+               T->Int32Constant(0), val, kNoWriteBarrier);
       T->Return(T->Int32Constant(CHECK_VALUE));
     } else {
       T->Return(val);
@@ -168,6 +352,7 @@
   }
 
  protected:
+  MachineType rep;
   CType p0;
   CType p1;
   CType result;
@@ -176,21 +361,31 @@
 
 // A helper class for testing code sequences that take two int parameters and
 // return an int value.
-class Int32BinopTester
-    : public BinopTester<int32_t, kMachInt32, USE_RETURN_REGISTER> {
+class Int32BinopTester : public BinopTester<int32_t, USE_RETURN_REGISTER> {
  public:
   explicit Int32BinopTester(RawMachineAssemblerTester<int32_t>* tester)
-      : BinopTester<int32_t, kMachInt32, USE_RETURN_REGISTER>(tester) {}
+      : BinopTester<int32_t, USE_RETURN_REGISTER>(tester,
+                                                  MachineType::Int32()) {}
+};
+
+
+// A helper class for testing code sequences that take two int parameters and
+// return an int value.
+class Int64BinopTester : public BinopTester<int64_t, USE_RETURN_REGISTER> {
+ public:
+  explicit Int64BinopTester(RawMachineAssemblerTester<int32_t>* tester)
+      : BinopTester<int64_t, USE_RETURN_REGISTER>(tester,
+                                                  MachineType::Int64()) {}
 };
 
 
 // A helper class for testing code sequences that take two uint parameters and
 // return an uint value.
-class Uint32BinopTester
-    : public BinopTester<uint32_t, kMachUint32, USE_RETURN_REGISTER> {
+class Uint32BinopTester : public BinopTester<uint32_t, USE_RETURN_REGISTER> {
  public:
   explicit Uint32BinopTester(RawMachineAssemblerTester<int32_t>* tester)
-      : BinopTester<uint32_t, kMachUint32, USE_RETURN_REGISTER>(tester) {}
+      : BinopTester<uint32_t, USE_RETURN_REGISTER>(tester,
+                                                   MachineType::Uint32()) {}
 
   uint32_t call(uint32_t a0, uint32_t a1) {
     p0 = a0;
@@ -200,14 +395,24 @@
 };
 
 
+// A helper class for testing code sequences that take two float parameters and
+// return a float value.
+// TODO(titzer): figure out how to return floats correctly on ia32.
+class Float32BinopTester : public BinopTester<float, USE_RESULT_BUFFER> {
+ public:
+  explicit Float32BinopTester(RawMachineAssemblerTester<int32_t>* tester)
+      : BinopTester<float, USE_RESULT_BUFFER>(tester, MachineType::Float32()) {}
+};
+
+
 // A helper class for testing code sequences that take two double parameters and
 // return a double value.
 // TODO(titzer): figure out how to return doubles correctly on ia32.
-class Float64BinopTester
-    : public BinopTester<double, kMachFloat64, USE_RESULT_BUFFER> {
+class Float64BinopTester : public BinopTester<double, USE_RESULT_BUFFER> {
  public:
   explicit Float64BinopTester(RawMachineAssemblerTester<int32_t>* tester)
-      : BinopTester<double, kMachFloat64, USE_RESULT_BUFFER>(tester) {}
+      : BinopTester<double, USE_RESULT_BUFFER>(tester, MachineType::Float64()) {
+  }
 };
 
 
@@ -215,22 +420,22 @@
 // and return a pointer value.
 // TODO(titzer): pick word size of pointers based on V8_TARGET.
 template <typename Type>
-class PointerBinopTester
-    : public BinopTester<Type*, kMachPtr, USE_RETURN_REGISTER> {
+class PointerBinopTester : public BinopTester<Type*, USE_RETURN_REGISTER> {
  public:
   explicit PointerBinopTester(RawMachineAssemblerTester<int32_t>* tester)
-      : BinopTester<Type*, kMachPtr, USE_RETURN_REGISTER>(tester) {}
+      : BinopTester<Type*, USE_RETURN_REGISTER>(tester,
+                                                MachineType::Pointer()) {}
 };
 
 
 // A helper class for testing code sequences that take two tagged parameters and
 // return a tagged value.
 template <typename Type>
-class TaggedBinopTester
-    : public BinopTester<Type*, kMachAnyTagged, USE_RETURN_REGISTER> {
+class TaggedBinopTester : public BinopTester<Type*, USE_RETURN_REGISTER> {
  public:
   explicit TaggedBinopTester(RawMachineAssemblerTester<int32_t>* tester)
-      : BinopTester<Type*, kMachAnyTagged, USE_RETURN_REGISTER>(tester) {}
+      : BinopTester<Type*, USE_RETURN_REGISTER>(tester,
+                                                MachineType::AnyTagged()) {}
 };
 
 // A helper class for testing compares. Wraps a machine opcode and provides
@@ -240,7 +445,7 @@
   explicit CompareWrapper(IrOpcode::Value op) : opcode(op) {}
 
   Node* MakeNode(RawMachineAssemblerTester<int32_t>* m, Node* a, Node* b) {
-    return m->NewNode(op(m->machine()), a, b);
+    return m->AddNode(op(m->machine()), a, b);
   }
 
   const Operator* op(MachineOperatorBuilder* machine) {
@@ -332,6 +537,24 @@
   void RunLeft(RawMachineAssemblerTester<int32_t>* m);
   void RunRight(RawMachineAssemblerTester<int32_t>* m);
 };
+
+// TODO(bmeurer): Drop this crap once we switch to GTest/Gmock.
+static inline void CheckFloatEq(volatile float x, volatile float y) {
+  if (std::isnan(x)) {
+    CHECK(std::isnan(y));
+  } else {
+    CHECK_EQ(x, y);
+  }
+}
+
+static inline void CheckDoubleEq(volatile double x, volatile double y) {
+  if (std::isnan(x)) {
+    CHECK(std::isnan(y));
+  } else {
+    CHECK_EQ(x, y);
+  }
+}
+
 }  // namespace compiler
 }  // namespace internal
 }  // namespace v8
diff --git a/test/cctest/compiler/function-tester.h b/test/cctest/compiler/function-tester.h
index 7e16eea..2fcd353 100644
--- a/test/cctest/compiler/function-tester.h
+++ b/test/cctest/compiler/function-tester.h
@@ -5,22 +5,18 @@
 #ifndef V8_CCTEST_COMPILER_FUNCTION_TESTER_H_
 #define V8_CCTEST_COMPILER_FUNCTION_TESTER_H_
 
-#include "src/v8.h"
-#include "test/cctest/cctest.h"
-
-#include "src/ast-numbering.h"
+#include "src/ast/ast-numbering.h"
+#include "src/ast/scopes.h"
 #include "src/compiler.h"
 #include "src/compiler/linkage.h"
 #include "src/compiler/pipeline.h"
 #include "src/execution.h"
-#include "src/full-codegen.h"
+#include "src/full-codegen/full-codegen.h"
 #include "src/handles.h"
 #include "src/objects-inl.h"
-#include "src/parser.h"
-#include "src/rewriter.h"
-#include "src/scopes.h"
-
-#define USE_CRANKSHAFT 0
+#include "src/parsing/parser.h"
+#include "src/parsing/rewriter.h"
+#include "test/cctest/cctest.h"
 
 namespace v8 {
 namespace internal {
@@ -33,48 +29,65 @@
         function((FLAG_allow_natives_syntax = true, NewFunction(source))),
         flags_(flags) {
     Compile(function);
-    const uint32_t supported_flags = CompilationInfo::kContextSpecializing |
-                                     CompilationInfo::kInliningEnabled |
-                                     CompilationInfo::kTypingEnabled;
-    CHECK_EQ(0, flags_ & ~supported_flags);
+    const uint32_t supported_flags =
+        CompilationInfo::kFunctionContextSpecializing |
+        CompilationInfo::kInliningEnabled | CompilationInfo::kTypingEnabled;
+    CHECK_EQ(0u, flags_ & ~supported_flags);
   }
 
-  explicit FunctionTester(Graph* graph)
+  FunctionTester(Graph* graph, int param_count)
       : isolate(main_isolate()),
-        function(NewFunction("(function(a,b){})")),
+        function(NewFunction(BuildFunction(param_count).c_str())),
         flags_(0) {
     CompileGraph(graph);
   }
 
+  FunctionTester(const CallInterfaceDescriptor& descriptor, Handle<Code> code)
+      : isolate(main_isolate()),
+        function(
+            (FLAG_allow_natives_syntax = true,
+             NewFunction(BuildFunctionFromDescriptor(descriptor).c_str()))),
+        flags_(0) {
+    Compile(function);
+    function->ReplaceCode(*code);
+  }
+
   Isolate* isolate;
   Handle<JSFunction> function;
 
+  MaybeHandle<Object> Call() {
+    return Execution::Call(isolate, function, undefined(), 0, nullptr);
+  }
+
   MaybeHandle<Object> Call(Handle<Object> a, Handle<Object> b) {
     Handle<Object> args[] = {a, b};
-    return Execution::Call(isolate, function, undefined(), 2, args, false);
+    return Execution::Call(isolate, function, undefined(), 2, args);
+  }
+
+  MaybeHandle<Object> Call(Handle<Object> a, Handle<Object> b, Handle<Object> c,
+                           Handle<Object> d) {
+    Handle<Object> args[] = {a, b, c, d};
+    return Execution::Call(isolate, function, undefined(), 4, args);
   }
 
   void CheckThrows(Handle<Object> a, Handle<Object> b) {
-    TryCatch try_catch;
+    TryCatch try_catch(reinterpret_cast<v8::Isolate*>(isolate));
     MaybeHandle<Object> no_result = Call(a, b);
     CHECK(isolate->has_pending_exception());
     CHECK(try_catch.HasCaught());
     CHECK(no_result.is_null());
-    // TODO(mstarzinger): Temporary workaround for issue chromium:362388.
     isolate->OptionalRescheduleException(true);
   }
 
-  v8::Handle<v8::Message> CheckThrowsReturnMessage(Handle<Object> a,
-                                                   Handle<Object> b) {
-    TryCatch try_catch;
+  v8::Local<v8::Message> CheckThrowsReturnMessage(Handle<Object> a,
+                                                  Handle<Object> b) {
+    TryCatch try_catch(reinterpret_cast<v8::Isolate*>(isolate));
     MaybeHandle<Object> no_result = Call(a, b);
     CHECK(isolate->has_pending_exception());
     CHECK(try_catch.HasCaught());
     CHECK(no_result.is_null());
-    // TODO(mstarzinger): Calling OptionalRescheduleException is a dirty hack,
-    // it's the only way to make Message() not to assert because an external
-    // exception has been caught by the try_catch.
     isolate->OptionalRescheduleException(true);
+    CHECK(!try_catch.Message().IsEmpty());
     return try_catch.Message();
   }
 
@@ -118,13 +131,13 @@
   }
 
   Handle<JSFunction> NewFunction(const char* source) {
-    return v8::Utils::OpenHandle(
-        *v8::Handle<v8::Function>::Cast(CompileRun(source)));
+    return Handle<JSFunction>::cast(v8::Utils::OpenHandle(
+        *v8::Local<v8::Function>::Cast(CompileRun(source))));
   }
 
   Handle<JSObject> NewObject(const char* source) {
-    return v8::Utils::OpenHandle(
-        *v8::Handle<v8::Object>::Cast(CompileRun(source)));
+    return Handle<JSObject>::cast(v8::Utils::OpenHandle(
+        *v8::Local<v8::Object>::Cast(CompileRun(source))));
   }
 
   Handle<String> Val(const char* string) {
@@ -151,13 +164,15 @@
 
   Handle<JSFunction> Compile(Handle<JSFunction> function) {
 // TODO(titzer): make this method private.
-#if V8_TURBOFAN_TARGET
-    CompilationInfoWithZone info(function);
+    Zone zone;
+    ParseInfo parse_info(&zone, function);
+    CompilationInfo info(&parse_info);
+    info.MarkAsDeoptimizationEnabled();
 
-    CHECK(Parser::Parse(&info));
+    CHECK(Parser::ParseStatic(info.parse_info()));
     info.SetOptimizing(BailoutId::None(), Handle<Code>(function->code()));
-    if (flags_ & CompilationInfo::kContextSpecializing) {
-      info.MarkAsContextSpecializing();
+    if (flags_ & CompilationInfo::kFunctionContextSpecializing) {
+      info.MarkAsFunctionContextSpecializing();
     }
     if (flags_ & CompilationInfo::kInliningEnabled) {
       info.MarkAsInliningEnabled();
@@ -165,37 +180,22 @@
     if (flags_ & CompilationInfo::kTypingEnabled) {
       info.MarkAsTypingEnabled();
     }
-    CHECK(Compiler::Analyze(&info));
+    CHECK(Compiler::Analyze(info.parse_info()));
     CHECK(Compiler::EnsureDeoptimizationSupport(&info));
 
     Pipeline pipeline(&info);
     Handle<Code> code = pipeline.GenerateCode();
-    if (FLAG_turbo_deoptimization) {
-      info.context()->native_context()->AddOptimizedCode(*code);
-    }
-
     CHECK(!code.is_null());
+    info.dependencies()->Commit(code);
+    info.context()->native_context()->AddOptimizedCode(*code);
     function->ReplaceCode(*code);
-#elif USE_CRANKSHAFT
-    Handle<Code> unoptimized = Handle<Code>(function->code());
-    Handle<Code> code = Compiler::GetOptimizedCode(function, unoptimized,
-                                                   Compiler::NOT_CONCURRENT);
-    CHECK(!code.is_null());
-#if ENABLE_DISASSEMBLER
-    if (FLAG_print_opt_code) {
-      CodeTracer::Scope tracing_scope(isolate->GetCodeTracer());
-      code->Disassemble("test code", tracing_scope.file());
-    }
-#endif
-    function->ReplaceCode(*code);
-#endif
     return function;
   }
 
-  static Handle<JSFunction> ForMachineGraph(Graph* graph) {
+  static Handle<JSFunction> ForMachineGraph(Graph* graph, int param_count) {
     JSFunction* p = NULL;
     {  // because of the implicit handle scope of FunctionTester.
-      FunctionTester f(graph);
+      FunctionTester f(graph, param_count);
       p = *f.function;
     }
     return Handle<JSFunction>(p);  // allocated in outer handle scope.
@@ -204,16 +204,36 @@
  private:
   uint32_t flags_;
 
+  std::string BuildFunction(int param_count) {
+    std::string function_string = "(function(";
+    if (param_count > 0) {
+      char next = 'a';
+      function_string += next;
+      while (param_count-- > 0) {
+        function_string += ',';
+        function_string += ++next;
+      }
+    }
+    function_string += "){})";
+    return function_string;
+  }
+
+  std::string BuildFunctionFromDescriptor(
+      const CallInterfaceDescriptor& descriptor) {
+    return BuildFunction(descriptor.GetParameterCount());
+  }
+
   // Compile the given machine graph instead of the source of the function
   // and replace the JSFunction's code with the result.
   Handle<JSFunction> CompileGraph(Graph* graph) {
-    CHECK(Pipeline::SupportedTarget());
-    CompilationInfoWithZone info(function);
+    Zone zone;
+    ParseInfo parse_info(&zone, function);
+    CompilationInfo info(&parse_info);
 
-    CHECK(Parser::Parse(&info));
+    CHECK(Parser::ParseStatic(info.parse_info()));
     info.SetOptimizing(BailoutId::None(),
                        Handle<Code>(function->shared()->code()));
-    CHECK(Compiler::Analyze(&info));
+    CHECK(Compiler::Analyze(info.parse_info()));
     CHECK(Compiler::EnsureDeoptimizationSupport(&info));
 
     Handle<Code> code = Pipeline::GenerateCodeForTesting(&info, graph);
@@ -222,8 +242,8 @@
     return function;
   }
 };
-}
-}
-}  // namespace v8::internal::compiler
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
 
 #endif  // V8_CCTEST_COMPILER_FUNCTION_TESTER_H_
diff --git a/test/cctest/compiler/graph-builder-tester.cc b/test/cctest/compiler/graph-builder-tester.cc
deleted file mode 100644
index b0f470b..0000000
--- a/test/cctest/compiler/graph-builder-tester.cc
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2014 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "test/cctest/compiler/graph-builder-tester.h"
-
-#include "src/compiler/linkage.h"
-#include "src/compiler/pipeline.h"
-
-namespace v8 {
-namespace internal {
-namespace compiler {
-
-MachineCallHelper::MachineCallHelper(Zone* zone, MachineSignature* machine_sig)
-    : CallHelper(zone->isolate(), machine_sig),
-      parameters_(NULL),
-      graph_(NULL) {}
-
-
-void MachineCallHelper::InitParameters(GraphBuilder* builder,
-                                       CommonOperatorBuilder* common) {
-  DCHECK_EQ(NULL, parameters_);
-  graph_ = builder->graph();
-  int param_count = static_cast<int>(parameter_count());
-  if (param_count == 0) return;
-  parameters_ = graph_->zone()->NewArray<Node*>(param_count);
-  for (int i = 0; i < param_count; ++i) {
-    parameters_[i] = builder->NewNode(common->Parameter(i), graph_->start());
-  }
-}
-
-
-byte* MachineCallHelper::Generate() {
-  DCHECK(parameter_count() == 0 || parameters_ != NULL);
-  if (!Pipeline::SupportedBackend()) return NULL;
-  if (code_.is_null()) {
-    Zone* zone = graph_->zone();
-    CallDescriptor* desc =
-        Linkage::GetSimplifiedCDescriptor(zone, machine_sig_);
-    code_ = Pipeline::GenerateCodeForTesting(desc, graph_);
-  }
-  return code_.ToHandleChecked()->entry();
-}
-
-
-Node* MachineCallHelper::Parameter(size_t index) {
-  DCHECK_NE(NULL, parameters_);
-  DCHECK(index < parameter_count());
-  return parameters_[index];
-}
-
-}  // namespace compiler
-}  // namespace internal
-}  // namespace v8
diff --git a/test/cctest/compiler/graph-builder-tester.h b/test/cctest/compiler/graph-builder-tester.h
index 772de4d..de2713a 100644
--- a/test/cctest/compiler/graph-builder-tester.h
+++ b/test/cctest/compiler/graph-builder-tester.h
@@ -5,67 +5,37 @@
 #ifndef V8_CCTEST_COMPILER_GRAPH_BUILDER_TESTER_H_
 #define V8_CCTEST_COMPILER_GRAPH_BUILDER_TESTER_H_
 
-#include "src/v8.h"
-#include "test/cctest/cctest.h"
-
 #include "src/compiler/common-operator.h"
-#include "src/compiler/graph-builder.h"
+#include "src/compiler/instruction-selector.h"
+#include "src/compiler/linkage.h"
 #include "src/compiler/machine-operator.h"
+#include "src/compiler/operator-properties.h"
+#include "src/compiler/pipeline.h"
 #include "src/compiler/simplified-operator.h"
+#include "test/cctest/cctest.h"
 #include "test/cctest/compiler/call-tester.h"
-#include "test/cctest/compiler/simplified-graph-builder.h"
 
 namespace v8 {
 namespace internal {
 namespace compiler {
 
-// A class that just passes node creation on to the Graph.
-class DirectGraphBuilder : public GraphBuilder {
- public:
-  explicit DirectGraphBuilder(Graph* graph) : GraphBuilder(graph) {}
-  virtual ~DirectGraphBuilder() {}
-
- protected:
-  virtual Node* MakeNode(const Operator* op, int value_input_count,
-                         Node** value_inputs, bool incomplete) FINAL {
-    return graph()->NewNode(op, value_input_count, value_inputs, incomplete);
-  }
-};
-
-
-class MachineCallHelper : public CallHelper {
- public:
-  MachineCallHelper(Zone* zone, MachineSignature* machine_sig);
-
-  Node* Parameter(size_t index);
-
-  void GenerateCode() { Generate(); }
-
- protected:
-  virtual byte* Generate();
-  void InitParameters(GraphBuilder* builder, CommonOperatorBuilder* common);
-
- protected:
-  size_t parameter_count() const { return machine_sig_->parameter_count(); }
-
- private:
-  Node** parameters_;
-  // TODO(dcarney): shouldn't need graph stored.
-  Graph* graph_;
-  MaybeHandle<Code> code_;
-};
-
-
 class GraphAndBuilders {
  public:
   explicit GraphAndBuilders(Zone* zone)
       : main_graph_(new (zone) Graph(zone)),
         main_common_(zone),
-        main_machine_(zone),
+        main_machine_(zone, MachineType::PointerRepresentation(),
+                      InstructionSelector::SupportedMachineOperatorFlags()),
         main_simplified_(zone) {}
 
+  Graph* graph() const { return main_graph_; }
+  Zone* zone() const { return graph()->zone(); }
+  CommonOperatorBuilder* common() { return &main_common_; }
+  MachineOperatorBuilder* machine() { return &main_machine_; }
+  SimplifiedOperatorBuilder* simplified() { return &main_simplified_; }
+
  protected:
-  // Prefixed with main_ to avoid naiming conflicts.
+  // Prefixed with main_ to avoid naming conflicts.
   Graph* main_graph_;
   CommonOperatorBuilder main_common_;
   MachineOperatorBuilder main_machine_;
@@ -74,33 +44,267 @@
 
 
 template <typename ReturnType>
-class GraphBuilderTester
-    : public HandleAndZoneScope,
-      private GraphAndBuilders,
-      public MachineCallHelper,
-      public SimplifiedGraphBuilder,
-      public CallHelper2<ReturnType, GraphBuilderTester<ReturnType> > {
+class GraphBuilderTester : public HandleAndZoneScope,
+                           public GraphAndBuilders,
+                           public CallHelper<ReturnType> {
  public:
-  explicit GraphBuilderTester(MachineType p0 = kMachNone,
-                              MachineType p1 = kMachNone,
-                              MachineType p2 = kMachNone,
-                              MachineType p3 = kMachNone,
-                              MachineType p4 = kMachNone)
+  explicit GraphBuilderTester(MachineType p0 = MachineType::None(),
+                              MachineType p1 = MachineType::None(),
+                              MachineType p2 = MachineType::None(),
+                              MachineType p3 = MachineType::None(),
+                              MachineType p4 = MachineType::None())
       : GraphAndBuilders(main_zone()),
-        MachineCallHelper(
-            main_zone(),
-            MakeMachineSignature(
-                main_zone(), ReturnValueTraits<ReturnType>::Representation(),
-                p0, p1, p2, p3, p4)),
-        SimplifiedGraphBuilder(main_graph_, &main_common_, &main_machine_,
-                               &main_simplified_) {
+        CallHelper<ReturnType>(
+            main_isolate(),
+            CSignature::New(main_zone(), MachineTypeForC<ReturnType>(), p0, p1,
+                            p2, p3, p4)),
+        effect_(NULL),
+        return_(NULL),
+        parameters_(main_zone()->template NewArray<Node*>(parameter_count())) {
     Begin(static_cast<int>(parameter_count()));
-    InitParameters(this, &main_common_);
+    InitParameters();
   }
   virtual ~GraphBuilderTester() {}
 
-  Factory* factory() const { return isolate()->factory(); }
+  void GenerateCode() { Generate(); }
+  Node* Parameter(size_t index) {
+    CHECK_LT(index, parameter_count());
+    return parameters_[index];
+  }
+
+  Isolate* isolate() { return main_isolate(); }
+  Factory* factory() { return isolate()->factory(); }
+
+  // Initialize graph and builder.
+  void Begin(int num_parameters) {
+    CHECK_NULL(graph()->start());
+    Node* start = graph()->NewNode(common()->Start(num_parameters + 3));
+    graph()->SetStart(start);
+    effect_ = start;
+  }
+
+  void Return(Node* value) {
+    return_ =
+        graph()->NewNode(common()->Return(), value, effect_, graph()->start());
+    effect_ = NULL;
+  }
+
+  // Close the graph.
+  void End() {
+    Node* end = graph()->NewNode(common()->End(1), return_);
+    graph()->SetEnd(end);
+  }
+
+  Node* PointerConstant(void* value) {
+    intptr_t intptr_value = reinterpret_cast<intptr_t>(value);
+    return kPointerSize == 8 ? NewNode(common()->Int64Constant(intptr_value))
+                             : Int32Constant(static_cast<int>(intptr_value));
+  }
+  Node* Int32Constant(int32_t value) {
+    return NewNode(common()->Int32Constant(value));
+  }
+  Node* HeapConstant(Handle<HeapObject> object) {
+    return NewNode(common()->HeapConstant(object));
+  }
+
+  Node* BooleanNot(Node* a) { return NewNode(simplified()->BooleanNot(), a); }
+
+  Node* NumberEqual(Node* a, Node* b) {
+    return NewNode(simplified()->NumberEqual(), a, b);
+  }
+  Node* NumberLessThan(Node* a, Node* b) {
+    return NewNode(simplified()->NumberLessThan(), a, b);
+  }
+  Node* NumberLessThanOrEqual(Node* a, Node* b) {
+    return NewNode(simplified()->NumberLessThanOrEqual(), a, b);
+  }
+  Node* NumberAdd(Node* a, Node* b) {
+    return NewNode(simplified()->NumberAdd(), a, b);
+  }
+  Node* NumberSubtract(Node* a, Node* b) {
+    return NewNode(simplified()->NumberSubtract(), a, b);
+  }
+  Node* NumberMultiply(Node* a, Node* b) {
+    return NewNode(simplified()->NumberMultiply(), a, b);
+  }
+  Node* NumberDivide(Node* a, Node* b) {
+    return NewNode(simplified()->NumberDivide(), a, b);
+  }
+  Node* NumberModulus(Node* a, Node* b) {
+    return NewNode(simplified()->NumberModulus(), a, b);
+  }
+  Node* NumberToInt32(Node* a) {
+    return NewNode(simplified()->NumberToInt32(), a);
+  }
+  Node* NumberToUint32(Node* a) {
+    return NewNode(simplified()->NumberToUint32(), a);
+  }
+
+  Node* StringEqual(Node* a, Node* b) {
+    return NewNode(simplified()->StringEqual(), a, b);
+  }
+  Node* StringLessThan(Node* a, Node* b) {
+    return NewNode(simplified()->StringLessThan(), a, b);
+  }
+  Node* StringLessThanOrEqual(Node* a, Node* b) {
+    return NewNode(simplified()->StringLessThanOrEqual(), a, b);
+  }
+
+  Node* ChangeTaggedToInt32(Node* a) {
+    return NewNode(simplified()->ChangeTaggedToInt32(), a);
+  }
+  Node* ChangeTaggedToUint32(Node* a) {
+    return NewNode(simplified()->ChangeTaggedToUint32(), a);
+  }
+  Node* ChangeTaggedToFloat64(Node* a) {
+    return NewNode(simplified()->ChangeTaggedToFloat64(), a);
+  }
+  Node* ChangeInt32ToTagged(Node* a) {
+    return NewNode(simplified()->ChangeInt32ToTagged(), a);
+  }
+  Node* ChangeUint32ToTagged(Node* a) {
+    return NewNode(simplified()->ChangeUint32ToTagged(), a);
+  }
+  Node* ChangeFloat64ToTagged(Node* a) {
+    return NewNode(simplified()->ChangeFloat64ToTagged(), a);
+  }
+  Node* ChangeBoolToBit(Node* a) {
+    return NewNode(simplified()->ChangeBoolToBit(), a);
+  }
+  Node* ChangeBitToBool(Node* a) {
+    return NewNode(simplified()->ChangeBitToBool(), a);
+  }
+
+  Node* LoadField(const FieldAccess& access, Node* object) {
+    return NewNode(simplified()->LoadField(access), object);
+  }
+  Node* StoreField(const FieldAccess& access, Node* object, Node* value) {
+    return NewNode(simplified()->StoreField(access), object, value);
+  }
+  Node* LoadElement(const ElementAccess& access, Node* object, Node* index) {
+    return NewNode(simplified()->LoadElement(access), object, index);
+  }
+  Node* StoreElement(const ElementAccess& access, Node* object, Node* index,
+                     Node* value) {
+    return NewNode(simplified()->StoreElement(access), object, index, value);
+  }
+
+  Node* NewNode(const Operator* op) {
+    return MakeNode(op, 0, static_cast<Node**>(NULL));
+  }
+
+  Node* NewNode(const Operator* op, Node* n1) { return MakeNode(op, 1, &n1); }
+
+  Node* NewNode(const Operator* op, Node* n1, Node* n2) {
+    Node* buffer[] = {n1, n2};
+    return MakeNode(op, arraysize(buffer), buffer);
+  }
+
+  Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3) {
+    Node* buffer[] = {n1, n2, n3};
+    return MakeNode(op, arraysize(buffer), buffer);
+  }
+
+  Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4) {
+    Node* buffer[] = {n1, n2, n3, n4};
+    return MakeNode(op, arraysize(buffer), buffer);
+  }
+
+  Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4,
+                Node* n5) {
+    Node* buffer[] = {n1, n2, n3, n4, n5};
+    return MakeNode(op, arraysize(buffer), buffer);
+  }
+
+  Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4,
+                Node* n5, Node* n6) {
+    Node* nodes[] = {n1, n2, n3, n4, n5, n6};
+    return MakeNode(op, arraysize(nodes), nodes);
+  }
+
+  Node* NewNode(const Operator* op, int value_input_count,
+                Node** value_inputs) {
+    return MakeNode(op, value_input_count, value_inputs);
+  }
+
+  Handle<Code> GetCode() {
+    Generate();
+    return code_.ToHandleChecked();
+  }
+
+ protected:
+  Node* MakeNode(const Operator* op, int value_input_count,
+                 Node** value_inputs) {
+    CHECK_EQ(op->ValueInputCount(), value_input_count);
+
+    CHECK(!OperatorProperties::HasContextInput(op));
+    CHECK_EQ(0, OperatorProperties::GetFrameStateInputCount(op));
+    bool has_control = op->ControlInputCount() == 1;
+    bool has_effect = op->EffectInputCount() == 1;
+
+    CHECK_LT(op->ControlInputCount(), 2);
+    CHECK_LT(op->EffectInputCount(), 2);
+
+    Node* result = NULL;
+    if (!has_control && !has_effect) {
+      result = graph()->NewNode(op, value_input_count, value_inputs);
+    } else {
+      int input_count_with_deps = value_input_count;
+      if (has_control) ++input_count_with_deps;
+      if (has_effect) ++input_count_with_deps;
+      Node** buffer = zone()->template NewArray<Node*>(input_count_with_deps);
+      memcpy(buffer, value_inputs, kPointerSize * value_input_count);
+      Node** current_input = buffer + value_input_count;
+      if (has_effect) {
+        *current_input++ = effect_;
+      }
+      if (has_control) {
+        *current_input++ = graph()->start();
+      }
+      result = graph()->NewNode(op, input_count_with_deps, buffer);
+      if (has_effect) {
+        effect_ = result;
+      }
+      // This graph builder does not support control flow.
+      CHECK_EQ(0, op->ControlOutputCount());
+    }
+
+    return result;
+  }
+
+  virtual byte* Generate() {
+    if (code_.is_null()) {
+      Zone* zone = graph()->zone();
+      CallDescriptor* desc =
+          Linkage::GetSimplifiedCDescriptor(zone, this->csig_);
+      CompilationInfo info("testing", main_isolate(), main_zone());
+      code_ = Pipeline::GenerateCodeForTesting(&info, desc, graph());
+#ifdef ENABLE_DISASSEMBLER
+      if (!code_.is_null() && FLAG_print_opt_code) {
+        OFStream os(stdout);
+        code_.ToHandleChecked()->Disassemble("test code", os);
+      }
+#endif
+    }
+    return code_.ToHandleChecked()->entry();
+  }
+
+  void InitParameters() {
+    int param_count = static_cast<int>(parameter_count());
+    for (int i = 0; i < param_count; ++i) {
+      parameters_[i] = this->NewNode(common()->Parameter(i), graph()->start());
+    }
+  }
+
+  size_t parameter_count() const { return this->csig_->parameter_count(); }
+
+ private:
+  Node* effect_;
+  Node* return_;
+  Node** parameters_;
+  MaybeHandle<Code> code_;
 };
+
 }  // namespace compiler
 }  // namespace internal
 }  // namespace v8
diff --git a/test/cctest/compiler/graph-tester.h b/test/cctest/compiler/graph-tester.h
deleted file mode 100644
index e569245..0000000
--- a/test/cctest/compiler/graph-tester.h
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2014 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef V8_CCTEST_COMPILER_GRAPH_TESTER_H_
-#define V8_CCTEST_COMPILER_GRAPH_TESTER_H_
-
-#include "src/v8.h"
-#include "test/cctest/cctest.h"
-
-#include "src/compiler/common-operator.h"
-#include "src/compiler/graph.h"
-
-namespace v8 {
-namespace internal {
-namespace compiler {
-
-class GraphTester : public HandleAndZoneScope, public Graph {
- public:
-  GraphTester() : Graph(main_zone()) {}
-};
-
-
-class GraphWithStartNodeTester : public GraphTester {
- public:
-  explicit GraphWithStartNodeTester(int num_parameters = 0)
-      : builder_(main_zone()),
-        start_node_(NewNode(builder_.Start(num_parameters))) {
-    SetStart(start_node_);
-  }
-
-  Node* start_node() { return start_node_; }
-
- private:
-  CommonOperatorBuilder builder_;
-  Node* start_node_;
-};
-}
-}
-}  // namespace v8::internal::compiler
-
-#endif  // V8_CCTEST_COMPILER_GRAPH_TESTER_H_
diff --git a/test/cctest/compiler/instruction-selector-tester.h b/test/cctest/compiler/instruction-selector-tester.h
deleted file mode 100644
index 3a28b2e..0000000
--- a/test/cctest/compiler/instruction-selector-tester.h
+++ /dev/null
@@ -1,127 +0,0 @@
-// Copyright 2014 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef V8_CCTEST_COMPILER_INSTRUCTION_SELECTOR_TEST_H_
-#define V8_CCTEST_COMPILER_INSTRUCTION_SELECTOR_TEST_H_
-
-#include <deque>
-#include <set>
-
-#include "src/compiler/instruction-selector.h"
-#include "src/compiler/raw-machine-assembler.h"
-#include "src/ostreams.h"
-#include "test/cctest/cctest.h"
-
-namespace v8 {
-namespace internal {
-namespace compiler {
-
-typedef std::set<int> VirtualRegisterSet;
-
-enum InstructionSelectorTesterMode { kTargetMode, kInternalMode };
-
-class InstructionSelectorTester : public HandleAndZoneScope,
-                                  public RawMachineAssembler {
- public:
-  enum Mode { kTargetMode, kInternalMode };
-
-  static const int kParameterCount = 3;
-  static MachineType* BuildParameterArray(Zone* zone) {
-    MachineType* array = zone->NewArray<MachineType>(kParameterCount);
-    for (int i = 0; i < kParameterCount; ++i) {
-      array[i] = kMachInt32;
-    }
-    return array;
-  }
-
-  InstructionSelectorTester()
-      : RawMachineAssembler(
-            new (main_zone()) Graph(main_zone()),
-            new (main_zone()) MachineCallDescriptorBuilder(
-                kMachInt32, kParameterCount, BuildParameterArray(main_zone())),
-            kMachPtr) {}
-
-  void SelectInstructions(CpuFeature feature) {
-    SelectInstructions(InstructionSelector::Features(feature));
-  }
-
-  void SelectInstructions(CpuFeature feature1, CpuFeature feature2) {
-    SelectInstructions(InstructionSelector::Features(feature1, feature2));
-  }
-
-  void SelectInstructions(Mode mode = kTargetMode) {
-    SelectInstructions(InstructionSelector::Features(), mode);
-  }
-
-  void SelectInstructions(InstructionSelector::Features features,
-                          Mode mode = kTargetMode) {
-    OFStream out(stdout);
-    Schedule* schedule = Export();
-    CHECK_NE(0, graph()->NodeCount());
-    CompilationInfo info(main_isolate(), main_zone());
-    Linkage linkage(&info, call_descriptor());
-    InstructionSequence sequence(&linkage, graph(), schedule);
-    SourcePositionTable source_positions(graph());
-    InstructionSelector selector(&sequence, &source_positions, features);
-    selector.SelectInstructions();
-    out << "--- Code sequence after instruction selection --- " << endl
-        << sequence;
-    for (InstructionSequence::const_iterator i = sequence.begin();
-         i != sequence.end(); ++i) {
-      Instruction* instr = *i;
-      if (instr->opcode() < 0) continue;
-      if (mode == kTargetMode) {
-        switch (ArchOpcodeField::decode(instr->opcode())) {
-#define CASE(Name) \
-  case k##Name:    \
-    break;
-          TARGET_ARCH_OPCODE_LIST(CASE)
-#undef CASE
-          default:
-            continue;
-        }
-      }
-      code.push_back(instr);
-    }
-    for (int vreg = 0; vreg < sequence.VirtualRegisterCount(); ++vreg) {
-      if (sequence.IsDouble(vreg)) {
-        CHECK(!sequence.IsReference(vreg));
-        doubles.insert(vreg);
-      }
-      if (sequence.IsReference(vreg)) {
-        CHECK(!sequence.IsDouble(vreg));
-        references.insert(vreg);
-      }
-    }
-    immediates.assign(sequence.immediates().begin(),
-                      sequence.immediates().end());
-  }
-
-  int32_t ToInt32(const InstructionOperand* operand) const {
-    size_t i = operand->index();
-    CHECK(i < immediates.size());
-    CHECK_EQ(InstructionOperand::IMMEDIATE, operand->kind());
-    return immediates[i].ToInt32();
-  }
-
-  std::deque<Instruction*> code;
-  VirtualRegisterSet doubles;
-  VirtualRegisterSet references;
-  std::deque<Constant> immediates;
-};
-
-
-static inline void CheckSameVreg(InstructionOperand* exp,
-                                 InstructionOperand* val) {
-  CHECK_EQ(InstructionOperand::UNALLOCATED, exp->kind());
-  CHECK_EQ(InstructionOperand::UNALLOCATED, val->kind());
-  CHECK_EQ(UnallocatedOperand::cast(exp)->virtual_register(),
-           UnallocatedOperand::cast(val)->virtual_register());
-}
-
-}  // namespace compiler
-}  // namespace internal
-}  // namespace v8
-
-#endif  // V8_CCTEST_COMPILER_INSTRUCTION_SELECTOR_TEST_H_
diff --git a/test/cctest/compiler/simplified-graph-builder.cc b/test/cctest/compiler/simplified-graph-builder.cc
deleted file mode 100644
index baa03fb..0000000
--- a/test/cctest/compiler/simplified-graph-builder.cc
+++ /dev/null
@@ -1,87 +0,0 @@
-// Copyright 2014 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "test/cctest/compiler/simplified-graph-builder.h"
-
-#include "src/compiler/operator-properties.h"
-
-namespace v8 {
-namespace internal {
-namespace compiler {
-
-SimplifiedGraphBuilder::SimplifiedGraphBuilder(
-    Graph* graph, CommonOperatorBuilder* common,
-    MachineOperatorBuilder* machine, SimplifiedOperatorBuilder* simplified)
-    : GraphBuilder(graph),
-      effect_(NULL),
-      return_(NULL),
-      common_(common),
-      machine_(machine),
-      simplified_(simplified) {}
-
-
-void SimplifiedGraphBuilder::Begin(int num_parameters) {
-  DCHECK(graph()->start() == NULL);
-  Node* start = graph()->NewNode(common()->Start(num_parameters));
-  graph()->SetStart(start);
-  effect_ = start;
-}
-
-
-void SimplifiedGraphBuilder::Return(Node* value) {
-  return_ =
-      graph()->NewNode(common()->Return(), value, effect_, graph()->start());
-  effect_ = NULL;
-}
-
-
-void SimplifiedGraphBuilder::End() {
-  Node* end = graph()->NewNode(common()->End(), return_);
-  graph()->SetEnd(end);
-}
-
-
-Node* SimplifiedGraphBuilder::MakeNode(const Operator* op,
-                                       int value_input_count,
-                                       Node** value_inputs, bool incomplete) {
-  DCHECK(op->ValueInputCount() == value_input_count);
-
-  DCHECK(!OperatorProperties::HasContextInput(op));
-  DCHECK(!OperatorProperties::HasFrameStateInput(op));
-  bool has_control = op->ControlInputCount() == 1;
-  bool has_effect = op->EffectInputCount() == 1;
-
-  DCHECK(op->ControlInputCount() < 2);
-  DCHECK(op->EffectInputCount() < 2);
-
-  Node* result = NULL;
-  if (!has_control && !has_effect) {
-    result = graph()->NewNode(op, value_input_count, value_inputs, incomplete);
-  } else {
-    int input_count_with_deps = value_input_count;
-    if (has_control) ++input_count_with_deps;
-    if (has_effect) ++input_count_with_deps;
-    Node** buffer = zone()->NewArray<Node*>(input_count_with_deps);
-    memcpy(buffer, value_inputs, kPointerSize * value_input_count);
-    Node** current_input = buffer + value_input_count;
-    if (has_effect) {
-      *current_input++ = effect_;
-    }
-    if (has_control) {
-      *current_input++ = graph()->start();
-    }
-    result = graph()->NewNode(op, input_count_with_deps, buffer, incomplete);
-    if (has_effect) {
-      effect_ = result;
-    }
-    // This graph builder does not support control flow.
-    CHECK_EQ(0, op->ControlOutputCount());
-  }
-
-  return result;
-}
-
-}  // namespace compiler
-}  // namespace internal
-}  // namespace v8
diff --git a/test/cctest/compiler/simplified-graph-builder.h b/test/cctest/compiler/simplified-graph-builder.h
deleted file mode 100644
index 537094a..0000000
--- a/test/cctest/compiler/simplified-graph-builder.h
+++ /dev/null
@@ -1,154 +0,0 @@
-// Copyright 2014 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef V8_CCTEST_COMPILER_SIMPLIFIED_GRAPH_BUILDER_H_
-#define V8_CCTEST_COMPILER_SIMPLIFIED_GRAPH_BUILDER_H_
-
-#include "src/compiler/common-operator.h"
-#include "src/compiler/graph-builder.h"
-#include "src/compiler/machine-operator.h"
-#include "src/compiler/simplified-operator.h"
-#include "test/cctest/cctest.h"
-#include "test/cctest/compiler/call-tester.h"
-
-namespace v8 {
-namespace internal {
-namespace compiler {
-
-class SimplifiedGraphBuilder : public GraphBuilder {
- public:
-  SimplifiedGraphBuilder(Graph* graph, CommonOperatorBuilder* common,
-                         MachineOperatorBuilder* machine,
-                         SimplifiedOperatorBuilder* simplified);
-  virtual ~SimplifiedGraphBuilder() {}
-
-  Zone* zone() const { return graph()->zone(); }
-  Isolate* isolate() const { return zone()->isolate(); }
-  CommonOperatorBuilder* common() const { return common_; }
-  MachineOperatorBuilder* machine() const { return machine_; }
-  SimplifiedOperatorBuilder* simplified() const { return simplified_; }
-
-  // Initialize graph and builder.
-  void Begin(int num_parameters);
-
-  void Return(Node* value);
-
-  // Close the graph.
-  void End();
-
-  Node* PointerConstant(void* value) {
-    intptr_t intptr_value = reinterpret_cast<intptr_t>(value);
-    return kPointerSize == 8 ? NewNode(common()->Int64Constant(intptr_value))
-                             : Int32Constant(static_cast<int>(intptr_value));
-  }
-  Node* Int32Constant(int32_t value) {
-    return NewNode(common()->Int32Constant(value));
-  }
-  Node* HeapConstant(Handle<HeapObject> object) {
-    Unique<HeapObject> val = Unique<HeapObject>::CreateUninitialized(object);
-    return NewNode(common()->HeapConstant(val));
-  }
-
-  Node* BooleanNot(Node* a) { return NewNode(simplified()->BooleanNot(), a); }
-
-  Node* NumberEqual(Node* a, Node* b) {
-    return NewNode(simplified()->NumberEqual(), a, b);
-  }
-  Node* NumberLessThan(Node* a, Node* b) {
-    return NewNode(simplified()->NumberLessThan(), a, b);
-  }
-  Node* NumberLessThanOrEqual(Node* a, Node* b) {
-    return NewNode(simplified()->NumberLessThanOrEqual(), a, b);
-  }
-  Node* NumberAdd(Node* a, Node* b) {
-    return NewNode(simplified()->NumberAdd(), a, b);
-  }
-  Node* NumberSubtract(Node* a, Node* b) {
-    return NewNode(simplified()->NumberSubtract(), a, b);
-  }
-  Node* NumberMultiply(Node* a, Node* b) {
-    return NewNode(simplified()->NumberMultiply(), a, b);
-  }
-  Node* NumberDivide(Node* a, Node* b) {
-    return NewNode(simplified()->NumberDivide(), a, b);
-  }
-  Node* NumberModulus(Node* a, Node* b) {
-    return NewNode(simplified()->NumberModulus(), a, b);
-  }
-  Node* NumberToInt32(Node* a) {
-    return NewNode(simplified()->NumberToInt32(), a);
-  }
-  Node* NumberToUint32(Node* a) {
-    return NewNode(simplified()->NumberToUint32(), a);
-  }
-
-  Node* StringEqual(Node* a, Node* b) {
-    return NewNode(simplified()->StringEqual(), a, b);
-  }
-  Node* StringLessThan(Node* a, Node* b) {
-    return NewNode(simplified()->StringLessThan(), a, b);
-  }
-  Node* StringLessThanOrEqual(Node* a, Node* b) {
-    return NewNode(simplified()->StringLessThanOrEqual(), a, b);
-  }
-  Node* StringAdd(Node* a, Node* b) {
-    return NewNode(simplified()->StringAdd(), a, b);
-  }
-
-  Node* ChangeTaggedToInt32(Node* a) {
-    return NewNode(simplified()->ChangeTaggedToInt32(), a);
-  }
-  Node* ChangeTaggedToUint32(Node* a) {
-    return NewNode(simplified()->ChangeTaggedToUint32(), a);
-  }
-  Node* ChangeTaggedToFloat64(Node* a) {
-    return NewNode(simplified()->ChangeTaggedToFloat64(), a);
-  }
-  Node* ChangeInt32ToTagged(Node* a) {
-    return NewNode(simplified()->ChangeInt32ToTagged(), a);
-  }
-  Node* ChangeUint32ToTagged(Node* a) {
-    return NewNode(simplified()->ChangeUint32ToTagged(), a);
-  }
-  Node* ChangeFloat64ToTagged(Node* a) {
-    return NewNode(simplified()->ChangeFloat64ToTagged(), a);
-  }
-  Node* ChangeBoolToBit(Node* a) {
-    return NewNode(simplified()->ChangeBoolToBit(), a);
-  }
-  Node* ChangeBitToBool(Node* a) {
-    return NewNode(simplified()->ChangeBitToBool(), a);
-  }
-
-  Node* LoadField(const FieldAccess& access, Node* object) {
-    return NewNode(simplified()->LoadField(access), object);
-  }
-  Node* StoreField(const FieldAccess& access, Node* object, Node* value) {
-    return NewNode(simplified()->StoreField(access), object, value);
-  }
-  Node* LoadElement(const ElementAccess& access, Node* object, Node* index) {
-    return NewNode(simplified()->LoadElement(access), object, index);
-  }
-  Node* StoreElement(const ElementAccess& access, Node* object, Node* index,
-                     Node* value) {
-    return NewNode(simplified()->StoreElement(access), object, index, value);
-  }
-
- protected:
-  virtual Node* MakeNode(const Operator* op, int value_input_count,
-                         Node** value_inputs, bool incomplete) FINAL;
-
- private:
-  Node* effect_;
-  Node* return_;
-  CommonOperatorBuilder* common_;
-  MachineOperatorBuilder* machine_;
-  SimplifiedOperatorBuilder* simplified_;
-};
-
-}  // namespace compiler
-}  // namespace internal
-}  // namespace v8
-
-#endif  // V8_CCTEST_COMPILER_SIMPLIFIED_GRAPH_BUILDER_H_
diff --git a/test/cctest/compiler/test-basic-block-profiler.cc b/test/cctest/compiler/test-basic-block-profiler.cc
index 703fc17..17400ab 100644
--- a/test/cctest/compiler/test-basic-block-profiler.cc
+++ b/test/cctest/compiler/test-basic-block-profiler.cc
@@ -2,29 +2,25 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "src/v8.h"
-
 #include "src/basic-block-profiler.h"
 #include "test/cctest/cctest.h"
 #include "test/cctest/compiler/codegen-tester.h"
 
-#if V8_TURBOFAN_TARGET
-
-using namespace v8::internal;
-using namespace v8::internal::compiler;
-
-typedef RawMachineAssembler::Label MLabel;
+namespace v8 {
+namespace internal {
+namespace compiler {
 
 class BasicBlockProfilerTest : public RawMachineAssemblerTester<int32_t> {
  public:
-  BasicBlockProfilerTest() : RawMachineAssemblerTester<int32_t>(kMachInt32) {
+  BasicBlockProfilerTest()
+      : RawMachineAssemblerTester<int32_t>(MachineType::Int32()) {
     FLAG_turbo_profiling = true;
   }
 
   void ResetCounts() { isolate()->basic_block_profiler()->ResetCounts(); }
 
   void Expect(size_t size, uint32_t* expected) {
-    CHECK_NE(NULL, isolate()->basic_block_profiler());
+    CHECK(isolate()->basic_block_profiler());
     const BasicBlockProfiler::DataList* l =
         isolate()->basic_block_profiler()->data_list();
     CHECK_NE(0, static_cast<int>(l->size()));
@@ -41,7 +37,7 @@
 TEST(ProfileDiamond) {
   BasicBlockProfilerTest m;
 
-  MLabel blocka, blockb, end;
+  RawMachineLabel blocka, blockb, end;
   m.Branch(m.Parameter(0), &blocka, &blockb);
   m.Bind(&blocka);
   m.Goto(&end);
@@ -81,12 +77,12 @@
 TEST(ProfileLoop) {
   BasicBlockProfilerTest m;
 
-  MLabel header, body, end;
+  RawMachineLabel header, body, end;
   Node* one = m.Int32Constant(1);
   m.Goto(&header);
 
   m.Bind(&header);
-  Node* count = m.Phi(kMachInt32, m.Parameter(0), one);
+  Node* count = m.Phi(MachineRepresentation::kWord32, m.Parameter(0), one);
   m.Branch(count, &body, &end);
 
   m.Bind(&body);
@@ -111,4 +107,6 @@
   }
 }
 
-#endif  // V8_TURBOFAN_TARGET
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/test/cctest/compiler/test-branch-combine.cc b/test/cctest/compiler/test-branch-combine.cc
index cd3472d..c3b4308 100644
--- a/test/cctest/compiler/test-branch-combine.cc
+++ b/test/cctest/compiler/test-branch-combine.cc
@@ -2,18 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "src/v8.h"
-
 #include "test/cctest/cctest.h"
 #include "test/cctest/compiler/codegen-tester.h"
 #include "test/cctest/compiler/value-helper.h"
 
-#if V8_TURBOFAN_TARGET
-
-using namespace v8::internal;
-using namespace v8::internal::compiler;
-
-typedef RawMachineAssembler::Label MLabel;
+namespace v8 {
+namespace internal {
+namespace compiler {
 
 static IrOpcode::Value int32cmp_opcodes[] = {
     IrOpcode::kWord32Equal, IrOpcode::kInt32LessThan,
@@ -23,12 +18,12 @@
 
 TEST(BranchCombineWord32EqualZero_1) {
   // Test combining a branch with x == 0
-  RawMachineAssemblerTester<int32_t> m(kMachInt32);
+  RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
   int32_t eq_constant = -1033;
   int32_t ne_constant = 825118;
   Node* p0 = m.Parameter(0);
 
-  MLabel blocka, blockb;
+  RawMachineLabel blocka, blockb;
   m.Branch(m.Word32Equal(p0, m.Int32Constant(0)), &blocka, &blockb);
   m.Bind(&blocka);
   m.Return(m.Int32Constant(eq_constant));
@@ -49,9 +44,9 @@
   int32_t ne_constant = 815118;
 
   for (int k = 0; k < 6; k++) {
-    RawMachineAssemblerTester<int32_t> m(kMachInt32);
+    RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
     Node* p0 = m.Parameter(0);
-    MLabel blocka, blockb;
+    RawMachineLabel blocka, blockb;
     Node* cond = p0;
     for (int j = 0; j < k; j++) {
       cond = m.Word32Equal(cond, m.Int32Constant(0));
@@ -74,12 +69,12 @@
 
 TEST(BranchCombineInt32LessThanZero_1) {
   // Test combining a branch with x < 0
-  RawMachineAssemblerTester<int32_t> m(kMachInt32);
+  RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
   int32_t eq_constant = -1433;
   int32_t ne_constant = 845118;
   Node* p0 = m.Parameter(0);
 
-  MLabel blocka, blockb;
+  RawMachineLabel blocka, blockb;
   m.Branch(m.Int32LessThan(p0, m.Int32Constant(0)), &blocka, &blockb);
   m.Bind(&blocka);
   m.Return(m.Int32Constant(eq_constant));
@@ -96,12 +91,12 @@
 
 TEST(BranchCombineUint32LessThan100_1) {
   // Test combining a branch with x < 100
-  RawMachineAssemblerTester<int32_t> m(kMachUint32);
+  RawMachineAssemblerTester<int32_t> m(MachineType::Uint32());
   int32_t eq_constant = 1471;
   int32_t ne_constant = 88845718;
   Node* p0 = m.Parameter(0);
 
-  MLabel blocka, blockb;
+  RawMachineLabel blocka, blockb;
   m.Branch(m.Uint32LessThan(p0, m.Int32Constant(100)), &blocka, &blockb);
   m.Bind(&blocka);
   m.Return(m.Int32Constant(eq_constant));
@@ -118,12 +113,12 @@
 
 TEST(BranchCombineUint32LessThanOrEqual100_1) {
   // Test combining a branch with x <= 100
-  RawMachineAssemblerTester<int32_t> m(kMachUint32);
+  RawMachineAssemblerTester<int32_t> m(MachineType::Uint32());
   int32_t eq_constant = 1479;
   int32_t ne_constant = 77845719;
   Node* p0 = m.Parameter(0);
 
-  MLabel blocka, blockb;
+  RawMachineLabel blocka, blockb;
   m.Branch(m.Uint32LessThanOrEqual(p0, m.Int32Constant(100)), &blocka, &blockb);
   m.Bind(&blocka);
   m.Return(m.Int32Constant(eq_constant));
@@ -140,12 +135,12 @@
 
 TEST(BranchCombineZeroLessThanInt32_1) {
   // Test combining a branch with 0 < x
-  RawMachineAssemblerTester<int32_t> m(kMachInt32);
+  RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
   int32_t eq_constant = -2033;
   int32_t ne_constant = 225118;
   Node* p0 = m.Parameter(0);
 
-  MLabel blocka, blockb;
+  RawMachineLabel blocka, blockb;
   m.Branch(m.Int32LessThan(m.Int32Constant(0), p0), &blocka, &blockb);
   m.Bind(&blocka);
   m.Return(m.Int32Constant(eq_constant));
@@ -162,12 +157,12 @@
 
 TEST(BranchCombineInt32GreaterThanZero_1) {
   // Test combining a branch with x > 0
-  RawMachineAssemblerTester<int32_t> m(kMachInt32);
+  RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
   int32_t eq_constant = -1073;
   int32_t ne_constant = 825178;
   Node* p0 = m.Parameter(0);
 
-  MLabel blocka, blockb;
+  RawMachineLabel blocka, blockb;
   m.Branch(m.Int32GreaterThan(p0, m.Int32Constant(0)), &blocka, &blockb);
   m.Bind(&blocka);
   m.Return(m.Int32Constant(eq_constant));
@@ -184,13 +179,14 @@
 
 TEST(BranchCombineWord32EqualP) {
   // Test combining a branch with an Word32Equal.
-  RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32);
+  RawMachineAssemblerTester<int32_t> m(MachineType::Int32(),
+                                       MachineType::Int32());
   int32_t eq_constant = -1035;
   int32_t ne_constant = 825018;
   Node* p0 = m.Parameter(0);
   Node* p1 = m.Parameter(1);
 
-  MLabel blocka, blockb;
+  RawMachineLabel blocka, blockb;
   m.Branch(m.Word32Equal(p0, p1), &blocka, &blockb);
   m.Bind(&blocka);
   m.Return(m.Int32Constant(eq_constant));
@@ -214,13 +210,13 @@
 
   for (int left = 0; left < 2; left++) {
     FOR_INT32_INPUTS(i) {
-      RawMachineAssemblerTester<int32_t> m(kMachInt32);
+      RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
       int32_t a = *i;
 
       Node* p0 = m.Int32Constant(a);
       Node* p1 = m.Parameter(0);
 
-      MLabel blocka, blockb;
+      RawMachineLabel blocka, blockb;
       if (left == 1) m.Branch(m.Word32Equal(p0, p1), &blocka, &blockb);
       if (left == 0) m.Branch(m.Word32Equal(p1, p0), &blocka, &blockb);
       m.Bind(&blocka);
@@ -243,11 +239,12 @@
   int32_t ne_constant = 725018;
 
   for (int op = 0; op < 2; op++) {
-    RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32);
+    RawMachineAssemblerTester<int32_t> m(MachineType::Int32(),
+                                         MachineType::Int32());
     Node* p0 = m.Parameter(0);
     Node* p1 = m.Parameter(1);
 
-    MLabel blocka, blockb;
+    RawMachineLabel blocka, blockb;
     if (op == 0) m.Branch(m.Int32LessThan(p0, p1), &blocka, &blockb);
     if (op == 1) m.Branch(m.Int32LessThanOrEqual(p0, p1), &blocka, &blockb);
     m.Bind(&blocka);
@@ -275,12 +272,12 @@
 
   for (int op = 0; op < 2; op++) {
     FOR_INT32_INPUTS(i) {
-      RawMachineAssemblerTester<int32_t> m(kMachInt32);
+      RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
       int32_t a = *i;
       Node* p0 = m.Int32Constant(a);
       Node* p1 = m.Parameter(0);
 
-      MLabel blocka, blockb;
+      RawMachineLabel blocka, blockb;
       if (op == 0) m.Branch(m.Int32LessThan(p0, p1), &blocka, &blockb);
       if (op == 1) m.Branch(m.Int32LessThanOrEqual(p0, p1), &blocka, &blockb);
       m.Bind(&blocka);
@@ -336,7 +333,7 @@
       : w(opcode), invert(i), true_first(t), eq_constant(eq), ne_constant(ne) {}
 
   virtual void gen(RawMachineAssemblerTester<int32_t>* m, Node* a, Node* b) {
-    MLabel blocka, blockb;
+    RawMachineLabel blocka, blockb;
     Node* cond = w.MakeNode(m, a, b);
     if (invert) cond = m->Word32Equal(cond, m->Int32Constant(0));
     m->Branch(cond, &blocka, &blockb);
@@ -415,7 +412,7 @@
 
 TEST(BranchCombineFloat64Compares) {
   double inf = V8_INFINITY;
-  double nan = v8::base::OS::nan_value();
+  double nan = std::numeric_limits<double>::quiet_NaN();
   double inputs[] = {0.0, 1.0, -1.0, -inf, inf, nan};
 
   int32_t eq_constant = -1733;
@@ -432,10 +429,10 @@
     CompareWrapper cmp = cmps[c];
     for (int invert = 0; invert < 2; invert++) {
       RawMachineAssemblerTester<int32_t> m;
-      Node* a = m.LoadFromPointer(&input_a, kMachFloat64);
-      Node* b = m.LoadFromPointer(&input_b, kMachFloat64);
+      Node* a = m.LoadFromPointer(&input_a, MachineType::Float64());
+      Node* b = m.LoadFromPointer(&input_b, MachineType::Float64());
 
-      MLabel blocka, blockb;
+      RawMachineLabel blocka, blockb;
       Node* cond = cmp.MakeNode(&m, a, b);
       if (invert) cond = m.Word32Equal(cond, m.Int32Constant(0));
       m.Branch(cond, &blocka, &blockb);
@@ -444,10 +441,10 @@
       m.Bind(&blockb);
       m.Return(m.Int32Constant(ne_constant));
 
-      for (size_t i = 0; i < arraysize(inputs); i++) {
-        for (size_t j = 0; j < arraysize(inputs); j += 2) {
+      for (size_t i = 0; i < arraysize(inputs); ++i) {
+        for (size_t j = 0; j < arraysize(inputs); ++j) {
           input_a = inputs[i];
-          input_b = inputs[i];
+          input_b = inputs[j];
           int32_t expected =
               invert ? (cmp.Float64Compare(input_a, input_b) ? ne_constant
                                                              : eq_constant)
@@ -459,4 +456,7 @@
     }
   }
 }
-#endif  // V8_TURBOFAN_TARGET
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/test/cctest/compiler/test-changes-lowering.cc b/test/cctest/compiler/test-changes-lowering.cc
index 5795754..e850da7 100644
--- a/test/cctest/compiler/test-changes-lowering.cc
+++ b/test/cctest/compiler/test-changes-lowering.cc
@@ -4,10 +4,11 @@
 
 #include <limits>
 
+#include "src/ast/scopes.h"
 #include "src/compiler/change-lowering.h"
 #include "src/compiler/control-builders.h"
 #include "src/compiler/js-graph.h"
-#include "src/compiler/node-properties-inl.h"
+#include "src/compiler/node-properties.h"
 #include "src/compiler/pipeline.h"
 #include "src/compiler/select-lowering.h"
 #include "src/compiler/simplified-lowering.h"
@@ -15,25 +16,26 @@
 #include "src/compiler/verifier.h"
 #include "src/execution.h"
 #include "src/globals.h"
-#include "src/parser.h"
-#include "src/rewriter.h"
-#include "src/scopes.h"
+#include "src/parsing/parser.h"
+#include "src/parsing/rewriter.h"
 #include "test/cctest/cctest.h"
 #include "test/cctest/compiler/codegen-tester.h"
 #include "test/cctest/compiler/function-tester.h"
 #include "test/cctest/compiler/graph-builder-tester.h"
 #include "test/cctest/compiler/value-helper.h"
 
-using namespace v8::internal;
-using namespace v8::internal::compiler;
+namespace v8 {
+namespace internal {
+namespace compiler {
 
 template <typename ReturnType>
 class ChangesLoweringTester : public GraphBuilderTester<ReturnType> {
  public:
-  explicit ChangesLoweringTester(MachineType p0 = kMachNone)
+  explicit ChangesLoweringTester(MachineType p0 = MachineType::None())
       : GraphBuilderTester<ReturnType>(p0),
         javascript(this->zone()),
-        jsgraph(this->graph(), this->common(), &javascript, this->machine()),
+        jsgraph(this->isolate(), this->graph(), this->common(), &javascript,
+                nullptr, this->machine()),
         function(Handle<JSFunction>::null()) {}
 
   JSOperatorBuilder javascript;
@@ -58,22 +60,22 @@
 
   void StoreFloat64(Node* node, double* ptr) {
     Node* ptr_node = this->PointerConstant(ptr);
-    this->Store(kMachFloat64, ptr_node, node);
+    this->Store(MachineType::Float64(), ptr_node, node);
   }
 
   Node* LoadInt32(int32_t* ptr) {
     Node* ptr_node = this->PointerConstant(ptr);
-    return this->Load(kMachInt32, ptr_node);
+    return this->Load(MachineType::Int32(), ptr_node);
   }
 
   Node* LoadUint32(uint32_t* ptr) {
     Node* ptr_node = this->PointerConstant(ptr);
-    return this->Load(kMachUint32, ptr_node);
+    return this->Load(MachineType::Uint32(), ptr_node);
   }
 
   Node* LoadFloat64(double* ptr) {
     Node* ptr_node = this->PointerConstant(ptr);
-    return this->Load(kMachFloat64, ptr_node);
+    return this->Load(MachineType::Float64(), ptr_node);
   }
 
   void CheckNumber(double expected, Object* number) {
@@ -87,7 +89,7 @@
     Node* change = this->graph()->NewNode(op, p0);
     Node* ret = this->graph()->NewNode(this->common()->Return(), change,
                                        this->start(), this->start());
-    Node* end = this->graph()->NewNode(this->common()->End(), ret);
+    Node* end = this->graph()->NewNode(this->common()->End(1), ret);
     this->graph()->SetEnd(end);
     LowerChange(change);
   }
@@ -103,7 +105,7 @@
         change, this->start(), this->start());
     Node* ret = this->graph()->NewNode(
         this->common()->Return(), this->Int32Constant(0), store, this->start());
-    Node* end = this->graph()->NewNode(this->common()->End(), ret);
+    Node* end = this->graph()->NewNode(this->common()->End(1), ret);
     this->graph()->SetEnd(end);
     LowerChange(change);
   }
@@ -118,20 +120,18 @@
     Node* change = this->graph()->NewNode(op, load);
     Node* ret = this->graph()->NewNode(this->common()->Return(), change,
                                        this->start(), this->start());
-    Node* end = this->graph()->NewNode(this->common()->End(), ret);
+    Node* end = this->graph()->NewNode(this->common()->End(1), ret);
     this->graph()->SetEnd(end);
     LowerChange(change);
   }
 
   void LowerChange(Node* change) {
     // Run the graph reducer with changes lowering on a single node.
-    CompilationInfo info(this->isolate(), this->zone());
-    Linkage linkage(this->zone(), &info);
-    Typer typer(this->graph(), info.context());
+    Typer typer(this->isolate(), this->graph());
     typer.Run();
-    ChangeLowering change_lowering(&jsgraph, &linkage);
+    ChangeLowering change_lowering(&jsgraph);
     SelectLowering select_lowering(this->graph(), this->common());
-    GraphReducer reducer(this->graph(), this->zone());
+    GraphReducer reducer(this->zone(), this->graph());
     reducer.AddReducer(&change_lowering);
     reducer.AddReducer(&select_lowering);
     reducer.ReduceNode(change);
@@ -145,10 +145,9 @@
 
 TEST(RunChangeTaggedToInt32) {
   // Build and lower a graph by hand.
-  ChangesLoweringTester<int32_t> t(kMachAnyTagged);
+  ChangesLoweringTester<int32_t> t(MachineType::AnyTagged());
   t.BuildAndLower(t.simplified()->ChangeTaggedToInt32());
 
-  if (Pipeline::SupportedTarget()) {
     FOR_INT32_INPUTS(i) {
       int32_t input = *i;
 
@@ -168,17 +167,15 @@
         int32_t result = t.Call(*number);
         CHECK_EQ(input, result);
       }
-    }
   }
 }
 
 
 TEST(RunChangeTaggedToUint32) {
   // Build and lower a graph by hand.
-  ChangesLoweringTester<uint32_t> t(kMachAnyTagged);
+  ChangesLoweringTester<uint32_t> t(MachineType::AnyTagged());
   t.BuildAndLower(t.simplified()->ChangeTaggedToUint32());
 
-  if (Pipeline::SupportedTarget()) {
     FOR_UINT32_INPUTS(i) {
       uint32_t input = *i;
 
@@ -199,20 +196,19 @@
         CHECK_EQ(static_cast<int32_t>(input), static_cast<int32_t>(result));
       }
     }
-  }
 }
 
 
 TEST(RunChangeTaggedToFloat64) {
-  ChangesLoweringTester<int32_t> t(kMachAnyTagged);
+  ChangesLoweringTester<int32_t> t(MachineType::AnyTagged());
   double result;
 
-  t.BuildStoreAndLower(
-      t.simplified()->ChangeTaggedToFloat64(),
-      t.machine()->Store(StoreRepresentation(kMachFloat64, kNoWriteBarrier)),
-      &result);
+  t.BuildStoreAndLower(t.simplified()->ChangeTaggedToFloat64(),
+                       t.machine()->Store(StoreRepresentation(
+                           MachineRepresentation::kFloat64, kNoWriteBarrier)),
+                       &result);
 
-  if (Pipeline::SupportedTarget()) {
+  {
     FOR_INT32_INPUTS(i) {
       int32_t input = *i;
 
@@ -235,19 +231,19 @@
     }
   }
 
-  if (Pipeline::SupportedTarget()) {
+  {
     FOR_FLOAT64_INPUTS(i) {
       double input = *i;
       {
         Handle<Object> number = t.factory()->NewNumber(input);
         t.Call(*number);
-        CHECK_EQ(input, result);
+        CheckDoubleEq(input, result);
       }
 
       {
         Handle<HeapNumber> number = t.factory()->NewHeapNumber(input);
         t.Call(*number);
-        CHECK_EQ(input, result);
+        CheckDoubleEq(input, result);
       }
     }
   }
@@ -255,16 +251,16 @@
 
 
 TEST(RunChangeBoolToBit) {
-  ChangesLoweringTester<int32_t> t(kMachAnyTagged);
+  ChangesLoweringTester<int32_t> t(MachineType::AnyTagged());
   t.BuildAndLower(t.simplified()->ChangeBoolToBit());
 
-  if (Pipeline::SupportedTarget()) {
+  {
     Object* true_obj = t.heap()->true_value();
     int32_t result = t.Call(true_obj);
     CHECK_EQ(1, result);
   }
 
-  if (Pipeline::SupportedTarget()) {
+  {
     Object* false_obj = t.heap()->false_value();
     int32_t result = t.Call(false_obj);
     CHECK_EQ(0, result);
@@ -273,125 +269,22 @@
 
 
 TEST(RunChangeBitToBool) {
-  ChangesLoweringTester<Object*> t(kMachInt32);
+  ChangesLoweringTester<Object*> t(MachineType::Int32());
   t.BuildAndLower(t.simplified()->ChangeBitToBool());
 
-  if (Pipeline::SupportedTarget()) {
+  {
     Object* result = t.Call(1);
     Object* true_obj = t.heap()->true_value();
     CHECK_EQ(true_obj, result);
   }
 
-  if (Pipeline::SupportedTarget()) {
+  {
     Object* result = t.Call(0);
     Object* false_obj = t.heap()->false_value();
     CHECK_EQ(false_obj, result);
   }
 }
 
-
-#if V8_TURBOFAN_BACKEND
-// TODO(titzer): disabled on ARM
-
-TEST(RunChangeInt32ToTaggedSmi) {
-  ChangesLoweringTester<Object*> t;
-  int32_t input;
-  t.BuildLoadAndLower(t.simplified()->ChangeInt32ToTagged(),
-                      t.machine()->Load(kMachInt32), &input);
-
-  if (Pipeline::SupportedTarget()) {
-    FOR_INT32_INPUTS(i) {
-      input = *i;
-      if (!Smi::IsValid(input)) continue;
-      Object* result = t.Call();
-      t.CheckNumber(static_cast<double>(input), result);
-    }
-  }
-}
-
-
-TEST(RunChangeUint32ToTaggedSmi) {
-  ChangesLoweringTester<Object*> t;
-  uint32_t input;
-  t.BuildLoadAndLower(t.simplified()->ChangeUint32ToTagged(),
-                      t.machine()->Load(kMachUint32), &input);
-
-  if (Pipeline::SupportedTarget()) {
-    FOR_UINT32_INPUTS(i) {
-      input = *i;
-      if (input > static_cast<uint32_t>(Smi::kMaxValue)) continue;
-      Object* result = t.Call();
-      double expected = static_cast<double>(input);
-      t.CheckNumber(expected, result);
-    }
-  }
-}
-
-
-TEST(RunChangeInt32ToTagged) {
-  ChangesLoweringTester<Object*> t;
-  int32_t input;
-  t.BuildLoadAndLower(t.simplified()->ChangeInt32ToTagged(),
-                      t.machine()->Load(kMachInt32), &input);
-
-  if (Pipeline::SupportedTarget()) {
-    for (int m = 0; m < 3; m++) {  // Try 3 GC modes.
-      FOR_INT32_INPUTS(i) {
-        if (m == 0) CcTest::heap()->EnableInlineAllocation();
-        if (m == 1) CcTest::heap()->DisableInlineAllocation();
-        if (m == 2) SimulateFullSpace(CcTest::heap()->new_space());
-
-        input = *i;
-        Object* result = t.CallWithPotentialGC<Object>();
-        t.CheckNumber(static_cast<double>(input), result);
-      }
-    }
-  }
-}
-
-
-TEST(RunChangeUint32ToTagged) {
-  ChangesLoweringTester<Object*> t;
-  uint32_t input;
-  t.BuildLoadAndLower(t.simplified()->ChangeUint32ToTagged(),
-                      t.machine()->Load(kMachUint32), &input);
-
-  if (Pipeline::SupportedTarget()) {
-    for (int m = 0; m < 3; m++) {  // Try 3 GC modes.
-      FOR_UINT32_INPUTS(i) {
-        if (m == 0) CcTest::heap()->EnableInlineAllocation();
-        if (m == 1) CcTest::heap()->DisableInlineAllocation();
-        if (m == 2) SimulateFullSpace(CcTest::heap()->new_space());
-
-        input = *i;
-        Object* result = t.CallWithPotentialGC<Object>();
-        double expected = static_cast<double>(input);
-        t.CheckNumber(expected, result);
-      }
-    }
-  }
-}
-
-
-TEST(RunChangeFloat64ToTagged) {
-  ChangesLoweringTester<Object*> t;
-  double input;
-  t.BuildLoadAndLower(t.simplified()->ChangeFloat64ToTagged(),
-                      t.machine()->Load(kMachFloat64), &input);
-
-  if (Pipeline::SupportedTarget()) {
-    for (int m = 0; m < 3; m++) {  // Try 3 GC modes.
-      FOR_FLOAT64_INPUTS(i) {
-        if (m == 0) CcTest::heap()->EnableInlineAllocation();
-        if (m == 1) CcTest::heap()->DisableInlineAllocation();
-        if (m == 2) SimulateFullSpace(CcTest::heap()->new_space());
-
-        input = *i;
-        Object* result = t.CallWithPotentialGC<Object>();
-        t.CheckNumber(input, result);
-      }
-    }
-  }
-}
-
-#endif  // V8_TURBOFAN_BACKEND
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/test/cctest/compiler/test-code-stub-assembler.cc b/test/cctest/compiler/test-code-stub-assembler.cc
new file mode 100644
index 0000000..d7a7a81
--- /dev/null
+++ b/test/cctest/compiler/test-code-stub-assembler.cc
@@ -0,0 +1,125 @@
+// Copyright 2015 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/interface-descriptors.h"
+#include "src/isolate.h"
+#include "test/cctest/compiler/function-tester.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+
+class CodeStubAssemblerTester : public CodeStubAssembler {
+ public:
+  CodeStubAssemblerTester(Isolate* isolate,
+                          const CallInterfaceDescriptor& descriptor)
+      : CodeStubAssembler(isolate, isolate->runtime_zone(), descriptor,
+                          Code::STUB, "test"),
+        scope_(isolate) {}
+
+ private:
+  HandleScope scope_;
+  LocalContext context_;
+};
+
+
+TEST(SimpleSmiReturn) {
+  Isolate* isolate(CcTest::InitIsolateOnce());
+  VoidDescriptor descriptor(isolate);
+  CodeStubAssemblerTester m(isolate, descriptor);
+  m.Return(m.SmiTag(m.Int32Constant(37)));
+  Handle<Code> code = m.GenerateCode();
+  FunctionTester ft(descriptor, code);
+  MaybeHandle<Object> result = ft.Call();
+  CHECK_EQ(37, Handle<Smi>::cast(result.ToHandleChecked())->value());
+}
+
+
+TEST(SimpleIntPtrReturn) {
+  Isolate* isolate(CcTest::InitIsolateOnce());
+  VoidDescriptor descriptor(isolate);
+  CodeStubAssemblerTester m(isolate, descriptor);
+  int test;
+  m.Return(m.IntPtrConstant(reinterpret_cast<intptr_t>(&test)));
+  Handle<Code> code = m.GenerateCode();
+  FunctionTester ft(descriptor, code);
+  MaybeHandle<Object> result = ft.Call();
+  CHECK_EQ(reinterpret_cast<intptr_t>(&test),
+           reinterpret_cast<intptr_t>(*result.ToHandleChecked()));
+}
+
+
+TEST(SimpleDoubleReturn) {
+  Isolate* isolate(CcTest::InitIsolateOnce());
+  VoidDescriptor descriptor(isolate);
+  CodeStubAssemblerTester m(isolate, descriptor);
+  m.Return(m.NumberConstant(0.5));
+  Handle<Code> code = m.GenerateCode();
+  FunctionTester ft(descriptor, code);
+  MaybeHandle<Object> result = ft.Call();
+  CHECK_EQ(0.5, Handle<HeapNumber>::cast(result.ToHandleChecked())->value());
+}
+
+
+TEST(SimpleCallRuntime1Arg) {
+  Isolate* isolate(CcTest::InitIsolateOnce());
+  VoidDescriptor descriptor(isolate);
+  CodeStubAssemblerTester m(isolate, descriptor);
+  Node* context = m.HeapConstant(Handle<Context>(isolate->native_context()));
+  Node* b = m.SmiTag(m.Int32Constant(256));
+  m.Return(m.CallRuntime(Runtime::kMathSqrt, context, b));
+  Handle<Code> code = m.GenerateCode();
+  FunctionTester ft(descriptor, code);
+  MaybeHandle<Object> result = ft.Call();
+  CHECK_EQ(16, Handle<Smi>::cast(result.ToHandleChecked())->value());
+}
+
+
+TEST(SimpleTailCallRuntime1Arg) {
+  Isolate* isolate(CcTest::InitIsolateOnce());
+  VoidDescriptor descriptor(isolate);
+  CodeStubAssemblerTester m(isolate, descriptor);
+  Node* context = m.HeapConstant(Handle<Context>(isolate->native_context()));
+  Node* b = m.SmiTag(m.Int32Constant(256));
+  m.TailCallRuntime(Runtime::kMathSqrt, context, b);
+  Handle<Code> code = m.GenerateCode();
+  FunctionTester ft(descriptor, code);
+  MaybeHandle<Object> result = ft.Call();
+  CHECK_EQ(16, Handle<Smi>::cast(result.ToHandleChecked())->value());
+}
+
+
+TEST(SimpleCallRuntime2Arg) {
+  Isolate* isolate(CcTest::InitIsolateOnce());
+  VoidDescriptor descriptor(isolate);
+  CodeStubAssemblerTester m(isolate, descriptor);
+  Node* context = m.HeapConstant(Handle<Context>(isolate->native_context()));
+  Node* a = m.SmiTag(m.Int32Constant(2));
+  Node* b = m.SmiTag(m.Int32Constant(4));
+  m.Return(m.CallRuntime(Runtime::kMathPow, context, a, b));
+  Handle<Code> code = m.GenerateCode();
+  FunctionTester ft(descriptor, code);
+  MaybeHandle<Object> result = ft.Call();
+  CHECK_EQ(16, Handle<Smi>::cast(result.ToHandleChecked())->value());
+}
+
+
+TEST(SimpleTailCallRuntime2Arg) {
+  Isolate* isolate(CcTest::InitIsolateOnce());
+  VoidDescriptor descriptor(isolate);
+  CodeStubAssemblerTester m(isolate, descriptor);
+  Node* context = m.HeapConstant(Handle<Context>(isolate->native_context()));
+  Node* a = m.SmiTag(m.Int32Constant(2));
+  Node* b = m.SmiTag(m.Int32Constant(4));
+  m.TailCallRuntime(Runtime::kMathPow, context, a, b);
+  Handle<Code> code = m.GenerateCode();
+  FunctionTester ft(descriptor, code);
+  MaybeHandle<Object> result = ft.Call();
+  CHECK_EQ(16, Handle<Smi>::cast(result.ToHandleChecked())->value());
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/test/cctest/compiler/test-codegen-deopt.cc b/test/cctest/compiler/test-codegen-deopt.cc
deleted file mode 100644
index 56afe7b..0000000
--- a/test/cctest/compiler/test-codegen-deopt.cc
+++ /dev/null
@@ -1,292 +0,0 @@
-// Copyright 2014 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "src/v8.h"
-#include "test/cctest/cctest.h"
-
-#include "src/compiler/code-generator.h"
-#include "src/compiler/common-operator.h"
-#include "src/compiler/graph.h"
-#include "src/compiler/instruction-selector.h"
-#include "src/compiler/machine-operator.h"
-#include "src/compiler/node.h"
-#include "src/compiler/operator.h"
-#include "src/compiler/raw-machine-assembler.h"
-#include "src/compiler/register-allocator.h"
-#include "src/compiler/schedule.h"
-
-#include "src/ast-numbering.h"
-#include "src/full-codegen.h"
-#include "src/parser.h"
-#include "src/rewriter.h"
-
-#include "test/cctest/compiler/c-signature.h"
-#include "test/cctest/compiler/function-tester.h"
-
-using namespace v8::internal;
-using namespace v8::internal::compiler;
-
-
-#if V8_TURBOFAN_TARGET
-
-typedef RawMachineAssembler::Label MLabel;
-typedef v8::internal::compiler::InstructionSequence TestInstrSeq;
-
-static Handle<JSFunction> NewFunction(const char* source) {
-  return v8::Utils::OpenHandle(
-      *v8::Handle<v8::Function>::Cast(CompileRun(source)));
-}
-
-
-class DeoptCodegenTester {
- public:
-  explicit DeoptCodegenTester(HandleAndZoneScope* scope, const char* src)
-      : scope_(scope),
-        function(NewFunction(src)),
-        info(function, scope->main_zone()),
-        bailout_id(-1) {
-    CHECK(Parser::Parse(&info));
-    info.SetOptimizing(BailoutId::None(), Handle<Code>(function->code()));
-    CHECK(Compiler::Analyze(&info));
-    CHECK(Compiler::EnsureDeoptimizationSupport(&info));
-
-    DCHECK(info.shared_info()->has_deoptimization_support());
-
-    graph = new (scope_->main_zone()) Graph(scope_->main_zone());
-  }
-
-  virtual ~DeoptCodegenTester() {}
-
-  void GenerateCodeFromSchedule(Schedule* schedule) {
-    OFStream os(stdout);
-    if (FLAG_trace_turbo) {
-      os << *schedule;
-    }
-    result_code = Pipeline::GenerateCodeForTesting(&info, graph, schedule);
-#ifdef OBJECT_PRINT
-    if (FLAG_print_opt_code || FLAG_trace_turbo) {
-      result_code->Print();
-    }
-#endif
-  }
-
-  Zone* zone() { return scope_->main_zone(); }
-
-  HandleAndZoneScope* scope_;
-  Handle<JSFunction> function;
-  CompilationInfo info;
-  BailoutId bailout_id;
-  Handle<Code> result_code;
-  TestInstrSeq* code;
-  Graph* graph;
-};
-
-
-class TrivialDeoptCodegenTester : public DeoptCodegenTester {
- public:
-  explicit TrivialDeoptCodegenTester(HandleAndZoneScope* scope)
-      : DeoptCodegenTester(scope,
-                           "function foo() { deopt(); return 42; }; foo") {}
-
-  void GenerateCode() {
-    GenerateCodeFromSchedule(BuildGraphAndSchedule(graph));
-  }
-
-  Schedule* BuildGraphAndSchedule(Graph* graph) {
-    CommonOperatorBuilder common(zone());
-
-    // Manually construct a schedule for the function below:
-    // function foo() {
-    //   deopt();
-    // }
-
-    CSignature1<Object*, Object*> sig;
-    RawMachineAssembler m(graph, &sig);
-
-    Handle<JSFunction> deopt_function =
-        NewFunction("function deopt() { %DeoptimizeFunction(foo); }; deopt");
-    Unique<JSFunction> deopt_fun_constant =
-        Unique<JSFunction>::CreateUninitialized(deopt_function);
-    Node* deopt_fun_node = m.NewNode(common.HeapConstant(deopt_fun_constant));
-
-    Handle<Context> caller_context(function->context(), CcTest::i_isolate());
-    Unique<Context> caller_context_constant =
-        Unique<Context>::CreateUninitialized(caller_context);
-    Node* caller_context_node =
-        m.NewNode(common.HeapConstant(caller_context_constant));
-
-    bailout_id = GetCallBailoutId();
-    Node* parameters = m.NewNode(common.StateValues(1), m.UndefinedConstant());
-    Node* locals = m.NewNode(common.StateValues(0));
-    Node* stack = m.NewNode(common.StateValues(0));
-
-    Node* state_node = m.NewNode(
-        common.FrameState(JS_FRAME, bailout_id,
-                          OutputFrameStateCombine::Ignore()),
-        parameters, locals, stack, caller_context_node, m.UndefinedConstant());
-
-    Handle<Context> context(deopt_function->context(), CcTest::i_isolate());
-    Unique<Context> context_constant =
-        Unique<Context>::CreateUninitialized(context);
-    Node* context_node = m.NewNode(common.HeapConstant(context_constant));
-
-    m.CallJS0(deopt_fun_node, m.UndefinedConstant(), context_node, state_node);
-
-    m.Return(m.UndefinedConstant());
-
-    // Schedule the graph:
-    Schedule* schedule = m.Export();
-
-    return schedule;
-  }
-
-  BailoutId GetCallBailoutId() {
-    ZoneList<Statement*>* body = info.function()->body();
-    for (int i = 0; i < body->length(); i++) {
-      if (body->at(i)->IsExpressionStatement() &&
-          body->at(i)->AsExpressionStatement()->expression()->IsCall()) {
-        return body->at(i)->AsExpressionStatement()->expression()->id();
-      }
-    }
-    CHECK(false);
-    return BailoutId(-1);
-  }
-};
-
-
-TEST(TurboTrivialDeoptCodegen) {
-  HandleAndZoneScope scope;
-  InitializedHandleScope handles;
-
-  FLAG_allow_natives_syntax = true;
-  FLAG_turbo_deoptimization = true;
-
-  TrivialDeoptCodegenTester t(&scope);
-  t.GenerateCode();
-
-  DeoptimizationInputData* data =
-      DeoptimizationInputData::cast(t.result_code->deoptimization_data());
-
-  // TODO(jarin) Find a way to test the safepoint.
-
-  // Check that we deoptimize to the right AST id.
-  CHECK_EQ(1, data->DeoptCount());
-  CHECK_EQ(t.bailout_id.ToInt(), data->AstId(0).ToInt());
-}
-
-
-TEST(TurboTrivialDeoptCodegenAndRun) {
-  HandleAndZoneScope scope;
-  InitializedHandleScope handles;
-
-  FLAG_allow_natives_syntax = true;
-  FLAG_turbo_deoptimization = true;
-
-  TrivialDeoptCodegenTester t(&scope);
-  t.GenerateCode();
-
-  t.function->ReplaceCode(*t.result_code);
-  t.info.context()->native_context()->AddOptimizedCode(*t.result_code);
-
-  Isolate* isolate = scope.main_isolate();
-  Handle<Object> result;
-  bool has_pending_exception =
-      !Execution::Call(isolate, t.function,
-                       isolate->factory()->undefined_value(), 0, NULL,
-                       false).ToHandle(&result);
-  CHECK(!has_pending_exception);
-  CHECK(result->SameValue(Smi::FromInt(42)));
-}
-
-
-class TrivialRuntimeDeoptCodegenTester : public DeoptCodegenTester {
- public:
-  explicit TrivialRuntimeDeoptCodegenTester(HandleAndZoneScope* scope)
-      : DeoptCodegenTester(
-            scope,
-            "function foo() { %DeoptimizeFunction(foo); return 42; }; foo") {}
-
-  void GenerateCode() {
-    GenerateCodeFromSchedule(BuildGraphAndSchedule(graph));
-  }
-
-  Schedule* BuildGraphAndSchedule(Graph* graph) {
-    CommonOperatorBuilder common(zone());
-
-    // Manually construct a schedule for the function below:
-    // function foo() {
-    //   %DeoptimizeFunction(foo);
-    // }
-
-    CSignature1<Object*, Object*> sig;
-    RawMachineAssembler m(graph, &sig);
-
-    Unique<HeapObject> this_fun_constant =
-        Unique<HeapObject>::CreateUninitialized(function);
-    Node* this_fun_node = m.NewNode(common.HeapConstant(this_fun_constant));
-
-    Handle<Context> context(function->context(), CcTest::i_isolate());
-    Unique<HeapObject> context_constant =
-        Unique<HeapObject>::CreateUninitialized(context);
-    Node* context_node = m.NewNode(common.HeapConstant(context_constant));
-
-    bailout_id = GetCallBailoutId();
-    Node* parameters = m.NewNode(common.StateValues(1), m.UndefinedConstant());
-    Node* locals = m.NewNode(common.StateValues(0));
-    Node* stack = m.NewNode(common.StateValues(0));
-
-    Node* state_node = m.NewNode(
-        common.FrameState(JS_FRAME, bailout_id,
-                          OutputFrameStateCombine::Ignore()),
-        parameters, locals, stack, context_node, m.UndefinedConstant());
-
-    m.CallRuntime1(Runtime::kDeoptimizeFunction, this_fun_node, context_node,
-                   state_node);
-
-    m.Return(m.UndefinedConstant());
-
-    // Schedule the graph:
-    Schedule* schedule = m.Export();
-
-    return schedule;
-  }
-
-  BailoutId GetCallBailoutId() {
-    ZoneList<Statement*>* body = info.function()->body();
-    for (int i = 0; i < body->length(); i++) {
-      if (body->at(i)->IsExpressionStatement() &&
-          body->at(i)->AsExpressionStatement()->expression()->IsCallRuntime()) {
-        return body->at(i)->AsExpressionStatement()->expression()->id();
-      }
-    }
-    CHECK(false);
-    return BailoutId(-1);
-  }
-};
-
-
-TEST(TurboTrivialRuntimeDeoptCodegenAndRun) {
-  HandleAndZoneScope scope;
-  InitializedHandleScope handles;
-
-  FLAG_allow_natives_syntax = true;
-  FLAG_turbo_deoptimization = true;
-
-  TrivialRuntimeDeoptCodegenTester t(&scope);
-  t.GenerateCode();
-
-  t.function->ReplaceCode(*t.result_code);
-  t.info.context()->native_context()->AddOptimizedCode(*t.result_code);
-
-  Isolate* isolate = scope.main_isolate();
-  Handle<Object> result;
-  bool has_pending_exception =
-      !Execution::Call(isolate, t.function,
-                       isolate->factory()->undefined_value(), 0, NULL,
-                       false).ToHandle(&result);
-  CHECK(!has_pending_exception);
-  CHECK(result->SameValue(Smi::FromInt(42)));
-}
-
-#endif
diff --git a/test/cctest/compiler/test-control-reducer.cc b/test/cctest/compiler/test-control-reducer.cc
deleted file mode 100644
index 03aa50b..0000000
--- a/test/cctest/compiler/test-control-reducer.cc
+++ /dev/null
@@ -1,1678 +0,0 @@
-// Copyright 2014 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "src/v8.h"
-#include "test/cctest/cctest.h"
-
-#include "src/base/bits.h"
-#include "src/compiler/common-operator.h"
-#include "src/compiler/control-reducer.h"
-#include "src/compiler/graph-inl.h"
-#include "src/compiler/js-graph.h"
-#include "src/compiler/node-properties-inl.h"
-
-using namespace v8::internal;
-using namespace v8::internal::compiler;
-
-static const size_t kNumLeafs = 4;
-
-// TODO(titzer): convert this whole file into unit tests.
-
-static int CheckInputs(Node* node, Node* i0 = NULL, Node* i1 = NULL,
-                       Node* i2 = NULL) {
-  int count = 3;
-  if (i2 == NULL) count = 2;
-  if (i1 == NULL) count = 1;
-  if (i0 == NULL) count = 0;
-  CHECK_EQ(count, node->InputCount());
-  if (i0 != NULL) CHECK_EQ(i0, node->InputAt(0));
-  if (i1 != NULL) CHECK_EQ(i1, node->InputAt(1));
-  if (i2 != NULL) CHECK_EQ(i2, node->InputAt(2));
-  return count;
-}
-
-
-static int CheckMerge(Node* node, Node* i0 = NULL, Node* i1 = NULL,
-                      Node* i2 = NULL) {
-  CHECK_EQ(IrOpcode::kMerge, node->opcode());
-  int count = CheckInputs(node, i0, i1, i2);
-  CHECK_EQ(count, node->op()->ControlInputCount());
-  return count;
-}
-
-
-static int CheckLoop(Node* node, Node* i0 = NULL, Node* i1 = NULL,
-                     Node* i2 = NULL) {
-  CHECK_EQ(IrOpcode::kLoop, node->opcode());
-  int count = CheckInputs(node, i0, i1, i2);
-  CHECK_EQ(count, node->op()->ControlInputCount());
-  return count;
-}
-
-
-bool IsUsedBy(Node* a, Node* b) {
-  for (UseIter i = a->uses().begin(); i != a->uses().end(); ++i) {
-    if (b == *i) return true;
-  }
-  return false;
-}
-
-
-// A helper for all tests dealing with ControlTester.
-class ControlReducerTester : HandleAndZoneScope {
- public:
-  ControlReducerTester()
-      : isolate(main_isolate()),
-        common(main_zone()),
-        graph(main_zone()),
-        jsgraph(&graph, &common, NULL, NULL),
-        start(graph.NewNode(common.Start(1))),
-        end(graph.NewNode(common.End(), start)),
-        p0(graph.NewNode(common.Parameter(0), start)),
-        zero(jsgraph.Int32Constant(0)),
-        one(jsgraph.OneConstant()),
-        half(jsgraph.Constant(0.5)),
-        self(graph.NewNode(common.Int32Constant(0xaabbccdd))),
-        dead(graph.NewNode(common.Dead())) {
-    graph.SetEnd(end);
-    graph.SetStart(start);
-    leaf[0] = zero;
-    leaf[1] = one;
-    leaf[2] = half;
-    leaf[3] = p0;
-  }
-
-  Isolate* isolate;
-  CommonOperatorBuilder common;
-  Graph graph;
-  JSGraph jsgraph;
-  Node* start;
-  Node* end;
-  Node* p0;
-  Node* zero;
-  Node* one;
-  Node* half;
-  Node* self;
-  Node* dead;
-  Node* leaf[kNumLeafs];
-
-  Node* Phi(Node* a) {
-    return SetSelfReferences(graph.NewNode(op(1, false), a, start));
-  }
-
-  Node* Phi(Node* a, Node* b) {
-    return SetSelfReferences(graph.NewNode(op(2, false), a, b, start));
-  }
-
-  Node* Phi(Node* a, Node* b, Node* c) {
-    return SetSelfReferences(graph.NewNode(op(3, false), a, b, c, start));
-  }
-
-  Node* Phi(Node* a, Node* b, Node* c, Node* d) {
-    return SetSelfReferences(graph.NewNode(op(4, false), a, b, c, d, start));
-  }
-
-  Node* EffectPhi(Node* a) {
-    return SetSelfReferences(graph.NewNode(op(1, true), a, start));
-  }
-
-  Node* EffectPhi(Node* a, Node* b) {
-    return SetSelfReferences(graph.NewNode(op(2, true), a, b, start));
-  }
-
-  Node* EffectPhi(Node* a, Node* b, Node* c) {
-    return SetSelfReferences(graph.NewNode(op(3, true), a, b, c, start));
-  }
-
-  Node* EffectPhi(Node* a, Node* b, Node* c, Node* d) {
-    return SetSelfReferences(graph.NewNode(op(4, true), a, b, c, d, start));
-  }
-
-  Node* SetSelfReferences(Node* node) {
-    for (Edge edge : node->input_edges()) {
-      if (edge.to() == self) node->ReplaceInput(edge.index(), node);
-    }
-    return node;
-  }
-
-  const Operator* op(int count, bool effect) {
-    return effect ? common.EffectPhi(count) : common.Phi(kMachAnyTagged, count);
-  }
-
-  void Trim() { ControlReducer::TrimGraph(main_zone(), &jsgraph); }
-
-  void ReduceGraph() {
-    ControlReducer::ReduceGraph(main_zone(), &jsgraph, &common);
-  }
-
-  // Checks one-step reduction of a phi.
-  void ReducePhi(Node* expect, Node* phi) {
-    Node* result = ControlReducer::ReducePhiForTesting(&jsgraph, &common, phi);
-    CHECK_EQ(expect, result);
-    ReducePhiIterative(expect, phi);  // iterative should give the same result.
-  }
-
-  void ReducePhiIterative(Node* expect, Node* phi) {
-    p0->ReplaceInput(0, start);  // hack: parameters may be trimmed.
-    Node* ret = graph.NewNode(common.Return(), phi, start, start);
-    Node* end = graph.NewNode(common.End(), ret);
-    graph.SetEnd(end);
-    ControlReducer::ReduceGraph(main_zone(), &jsgraph, &common);
-    CheckInputs(end, ret);
-    CheckInputs(ret, expect, start, start);
-  }
-
-  void ReduceMerge(Node* expect, Node* merge) {
-    Node* result =
-        ControlReducer::ReduceMergeForTesting(&jsgraph, &common, merge);
-    CHECK_EQ(expect, result);
-  }
-
-  void ReduceMergeIterative(Node* expect, Node* merge) {
-    p0->ReplaceInput(0, start);  // hack: parameters may be trimmed.
-    Node* end = graph.NewNode(common.End(), merge);
-    graph.SetEnd(end);
-    ReduceGraph();
-    CheckInputs(end, expect);
-  }
-
-  void ReduceBranch(Node* expect, Node* branch) {
-    Node* result =
-        ControlReducer::ReduceBranchForTesting(&jsgraph, &common, branch);
-    CHECK_EQ(expect, result);
-  }
-
-  Node* Return(Node* val, Node* effect, Node* control) {
-    Node* ret = graph.NewNode(common.Return(), val, effect, control);
-    end->ReplaceInput(0, ret);
-    return ret;
-  }
-};
-
-
-TEST(Trim1_live) {
-  ControlReducerTester T;
-  CHECK(IsUsedBy(T.start, T.p0));
-  T.graph.SetEnd(T.p0);
-  T.Trim();
-  CHECK(IsUsedBy(T.start, T.p0));
-  CheckInputs(T.p0, T.start);
-}
-
-
-TEST(Trim1_dead) {
-  ControlReducerTester T;
-  CHECK(IsUsedBy(T.start, T.p0));
-  T.Trim();
-  CHECK(!IsUsedBy(T.start, T.p0));
-  CHECK_EQ(NULL, T.p0->InputAt(0));
-}
-
-
-TEST(Trim2_live) {
-  ControlReducerTester T;
-  Node* phi =
-      T.graph.NewNode(T.common.Phi(kMachAnyTagged, 2), T.one, T.half, T.start);
-  CHECK(IsUsedBy(T.one, phi));
-  CHECK(IsUsedBy(T.half, phi));
-  CHECK(IsUsedBy(T.start, phi));
-  T.graph.SetEnd(phi);
-  T.Trim();
-  CHECK(IsUsedBy(T.one, phi));
-  CHECK(IsUsedBy(T.half, phi));
-  CHECK(IsUsedBy(T.start, phi));
-  CheckInputs(phi, T.one, T.half, T.start);
-}
-
-
-TEST(Trim2_dead) {
-  ControlReducerTester T;
-  Node* phi =
-      T.graph.NewNode(T.common.Phi(kMachAnyTagged, 2), T.one, T.half, T.start);
-  CHECK(IsUsedBy(T.one, phi));
-  CHECK(IsUsedBy(T.half, phi));
-  CHECK(IsUsedBy(T.start, phi));
-  T.Trim();
-  CHECK(!IsUsedBy(T.one, phi));
-  CHECK(!IsUsedBy(T.half, phi));
-  CHECK(!IsUsedBy(T.start, phi));
-  CHECK_EQ(NULL, phi->InputAt(0));
-  CHECK_EQ(NULL, phi->InputAt(1));
-  CHECK_EQ(NULL, phi->InputAt(2));
-}
-
-
-TEST(Trim_chain1) {
-  ControlReducerTester T;
-  const int kDepth = 15;
-  Node* live[kDepth];
-  Node* dead[kDepth];
-  Node* end = T.start;
-  for (int i = 0; i < kDepth; i++) {
-    live[i] = end = T.graph.NewNode(T.common.Merge(1), end);
-    dead[i] = T.graph.NewNode(T.common.Merge(1), end);
-  }
-  // end         -> live[last] ->  live[last-1] -> ... -> start
-  //     dead[last] ^ dead[last-1] ^ ...                  ^
-  T.graph.SetEnd(end);
-  T.Trim();
-  for (int i = 0; i < kDepth; i++) {
-    CHECK(!IsUsedBy(live[i], dead[i]));
-    CHECK_EQ(NULL, dead[i]->InputAt(0));
-    CHECK_EQ(i == 0 ? T.start : live[i - 1], live[i]->InputAt(0));
-  }
-}
-
-
-TEST(Trim_chain2) {
-  ControlReducerTester T;
-  const int kDepth = 15;
-  Node* live[kDepth];
-  Node* dead[kDepth];
-  Node* l = T.start;
-  Node* d = T.start;
-  for (int i = 0; i < kDepth; i++) {
-    live[i] = l = T.graph.NewNode(T.common.Merge(1), l);
-    dead[i] = d = T.graph.NewNode(T.common.Merge(1), d);
-  }
-  // end -> live[last] -> live[last-1] -> ... -> start
-  //        dead[last] -> dead[last-1] -> ... -> start
-  T.graph.SetEnd(l);
-  T.Trim();
-  CHECK(!IsUsedBy(T.start, dead[0]));
-  for (int i = 0; i < kDepth; i++) {
-    CHECK_EQ(i == 0 ? NULL : dead[i - 1], dead[i]->InputAt(0));
-    CHECK_EQ(i == 0 ? T.start : live[i - 1], live[i]->InputAt(0));
-  }
-}
-
-
-TEST(Trim_cycle1) {
-  ControlReducerTester T;
-  Node* loop = T.graph.NewNode(T.common.Loop(1), T.start, T.start);
-  loop->ReplaceInput(1, loop);
-  Node* end = T.graph.NewNode(T.common.End(), loop);
-  T.graph.SetEnd(end);
-
-  CHECK(IsUsedBy(T.start, loop));
-  CHECK(IsUsedBy(loop, end));
-  CHECK(IsUsedBy(loop, loop));
-
-  T.Trim();
-
-  // nothing should have happened to the loop itself.
-  CHECK(IsUsedBy(T.start, loop));
-  CHECK(IsUsedBy(loop, end));
-  CHECK(IsUsedBy(loop, loop));
-  CheckInputs(loop, T.start, loop);
-  CheckInputs(end, loop);
-}
-
-
-TEST(Trim_cycle2) {
-  ControlReducerTester T;
-  Node* loop = T.graph.NewNode(T.common.Loop(2), T.start, T.start);
-  loop->ReplaceInput(1, loop);
-  Node* end = T.graph.NewNode(T.common.End(), loop);
-  Node* phi =
-      T.graph.NewNode(T.common.Phi(kMachAnyTagged, 2), T.one, T.half, loop);
-  T.graph.SetEnd(end);
-
-  CHECK(IsUsedBy(T.start, loop));
-  CHECK(IsUsedBy(loop, end));
-  CHECK(IsUsedBy(loop, loop));
-  CHECK(IsUsedBy(loop, phi));
-  CHECK(IsUsedBy(T.one, phi));
-  CHECK(IsUsedBy(T.half, phi));
-
-  T.Trim();
-
-  // nothing should have happened to the loop itself.
-  CHECK(IsUsedBy(T.start, loop));
-  CHECK(IsUsedBy(loop, end));
-  CHECK(IsUsedBy(loop, loop));
-  CheckInputs(loop, T.start, loop);
-  CheckInputs(end, loop);
-
-  // phi should have been trimmed away.
-  CHECK(!IsUsedBy(loop, phi));
-  CHECK(!IsUsedBy(T.one, phi));
-  CHECK(!IsUsedBy(T.half, phi));
-  CHECK_EQ(NULL, phi->InputAt(0));
-  CHECK_EQ(NULL, phi->InputAt(1));
-  CHECK_EQ(NULL, phi->InputAt(2));
-}
-
-
-void CheckTrimConstant(ControlReducerTester* T, Node* k) {
-  Node* phi = T->graph.NewNode(T->common.Phi(kMachInt32, 1), k, T->start);
-  CHECK(IsUsedBy(k, phi));
-  T->Trim();
-  CHECK(!IsUsedBy(k, phi));
-  CHECK_EQ(NULL, phi->InputAt(0));
-  CHECK_EQ(NULL, phi->InputAt(1));
-}
-
-
-TEST(Trim_constants) {
-  ControlReducerTester T;
-  int32_t int32_constants[] = {
-      0, -1,  -2,  2,  2,  3,  3,  4,  4,  5,  5,  4,  5,  6, 6, 7, 8, 7, 8, 9,
-      0, -11, -12, 12, 12, 13, 13, 14, 14, 15, 15, 14, 15, 6, 6, 7, 8, 7, 8, 9};
-
-  for (size_t i = 0; i < arraysize(int32_constants); i++) {
-    CheckTrimConstant(&T, T.jsgraph.Int32Constant(int32_constants[i]));
-    CheckTrimConstant(&T, T.jsgraph.Float64Constant(int32_constants[i]));
-    CheckTrimConstant(&T, T.jsgraph.Constant(int32_constants[i]));
-  }
-
-  Node* other_constants[] = {
-      T.jsgraph.UndefinedConstant(), T.jsgraph.TheHoleConstant(),
-      T.jsgraph.TrueConstant(),      T.jsgraph.FalseConstant(),
-      T.jsgraph.NullConstant(),      T.jsgraph.ZeroConstant(),
-      T.jsgraph.OneConstant(),       T.jsgraph.NaNConstant(),
-      T.jsgraph.Constant(21),        T.jsgraph.Constant(22.2)};
-
-  for (size_t i = 0; i < arraysize(other_constants); i++) {
-    CheckTrimConstant(&T, other_constants[i]);
-  }
-}
-
-
-TEST(CReducePhi1) {
-  ControlReducerTester R;
-
-  R.ReducePhi(R.leaf[0], R.Phi(R.leaf[0]));
-  R.ReducePhi(R.leaf[1], R.Phi(R.leaf[1]));
-  R.ReducePhi(R.leaf[2], R.Phi(R.leaf[2]));
-  R.ReducePhi(R.leaf[3], R.Phi(R.leaf[3]));
-}
-
-
-TEST(CReducePhi1_dead) {
-  ControlReducerTester R;
-
-  R.ReducePhi(R.leaf[0], R.Phi(R.leaf[0], R.dead));
-  R.ReducePhi(R.leaf[1], R.Phi(R.leaf[1], R.dead));
-  R.ReducePhi(R.leaf[2], R.Phi(R.leaf[2], R.dead));
-  R.ReducePhi(R.leaf[3], R.Phi(R.leaf[3], R.dead));
-
-  R.ReducePhi(R.leaf[0], R.Phi(R.dead, R.leaf[0]));
-  R.ReducePhi(R.leaf[1], R.Phi(R.dead, R.leaf[1]));
-  R.ReducePhi(R.leaf[2], R.Phi(R.dead, R.leaf[2]));
-  R.ReducePhi(R.leaf[3], R.Phi(R.dead, R.leaf[3]));
-}
-
-
-TEST(CReducePhi1_dead2) {
-  ControlReducerTester R;
-
-  R.ReducePhi(R.leaf[0], R.Phi(R.leaf[0], R.dead, R.dead));
-  R.ReducePhi(R.leaf[0], R.Phi(R.dead, R.leaf[0], R.dead));
-  R.ReducePhi(R.leaf[0], R.Phi(R.dead, R.dead, R.leaf[0]));
-}
-
-
-TEST(CReducePhi2a) {
-  ControlReducerTester R;
-
-  for (size_t i = 0; i < kNumLeafs; i++) {
-    Node* a = R.leaf[i];
-    R.ReducePhi(a, R.Phi(a, a));
-  }
-}
-
-
-TEST(CReducePhi2b) {
-  ControlReducerTester R;
-
-  for (size_t i = 0; i < kNumLeafs; i++) {
-    Node* a = R.leaf[i];
-    R.ReducePhi(a, R.Phi(R.self, a));
-    R.ReducePhi(a, R.Phi(a, R.self));
-  }
-}
-
-
-TEST(CReducePhi2c) {
-  ControlReducerTester R;
-
-  for (size_t i = 1; i < kNumLeafs; i++) {
-    Node* a = R.leaf[i], *b = R.leaf[0];
-    Node* phi1 = R.Phi(b, a);
-    R.ReducePhi(phi1, phi1);
-
-    Node* phi2 = R.Phi(a, b);
-    R.ReducePhi(phi2, phi2);
-  }
-}
-
-
-TEST(CReducePhi2_dead) {
-  ControlReducerTester R;
-
-  for (size_t i = 0; i < kNumLeafs; i++) {
-    Node* a = R.leaf[i];
-    R.ReducePhi(a, R.Phi(a, a, R.dead));
-    R.ReducePhi(a, R.Phi(a, R.dead, a));
-    R.ReducePhi(a, R.Phi(R.dead, a, a));
-  }
-
-  for (size_t i = 0; i < kNumLeafs; i++) {
-    Node* a = R.leaf[i];
-    R.ReducePhi(a, R.Phi(R.self, a));
-    R.ReducePhi(a, R.Phi(a, R.self));
-    R.ReducePhi(a, R.Phi(R.self, a, R.dead));
-    R.ReducePhi(a, R.Phi(a, R.self, R.dead));
-  }
-
-  for (size_t i = 1; i < kNumLeafs; i++) {
-    Node* a = R.leaf[i], *b = R.leaf[0];
-    Node* phi1 = R.Phi(b, a, R.dead);
-    R.ReducePhi(phi1, phi1);
-
-    Node* phi2 = R.Phi(a, b, R.dead);
-    R.ReducePhi(phi2, phi2);
-  }
-}
-
-
-TEST(CReducePhi3) {
-  ControlReducerTester R;
-
-  for (size_t i = 0; i < kNumLeafs; i++) {
-    Node* a = R.leaf[i];
-    R.ReducePhi(a, R.Phi(a, a, a));
-  }
-
-  for (size_t i = 0; i < kNumLeafs; i++) {
-    Node* a = R.leaf[i];
-    R.ReducePhi(a, R.Phi(R.self, a, a));
-    R.ReducePhi(a, R.Phi(a, R.self, a));
-    R.ReducePhi(a, R.Phi(a, a, R.self));
-  }
-
-  for (size_t i = 1; i < kNumLeafs; i++) {
-    Node* a = R.leaf[i], *b = R.leaf[0];
-    Node* phi1 = R.Phi(b, a, a);
-    R.ReducePhi(phi1, phi1);
-
-    Node* phi2 = R.Phi(a, b, a);
-    R.ReducePhi(phi2, phi2);
-
-    Node* phi3 = R.Phi(a, a, b);
-    R.ReducePhi(phi3, phi3);
-  }
-}
-
-
-TEST(CReducePhi4) {
-  ControlReducerTester R;
-
-  for (size_t i = 0; i < kNumLeafs; i++) {
-    Node* a = R.leaf[i];
-    R.ReducePhi(a, R.Phi(a, a, a, a));
-  }
-
-  for (size_t i = 0; i < kNumLeafs; i++) {
-    Node* a = R.leaf[i];
-    R.ReducePhi(a, R.Phi(R.self, a, a, a));
-    R.ReducePhi(a, R.Phi(a, R.self, a, a));
-    R.ReducePhi(a, R.Phi(a, a, R.self, a));
-    R.ReducePhi(a, R.Phi(a, a, a, R.self));
-
-    R.ReducePhi(a, R.Phi(R.self, R.self, a, a));
-    R.ReducePhi(a, R.Phi(a, R.self, R.self, a));
-    R.ReducePhi(a, R.Phi(a, a, R.self, R.self));
-    R.ReducePhi(a, R.Phi(R.self, a, a, R.self));
-  }
-
-  for (size_t i = 1; i < kNumLeafs; i++) {
-    Node* a = R.leaf[i], *b = R.leaf[0];
-    Node* phi1 = R.Phi(b, a, a, a);
-    R.ReducePhi(phi1, phi1);
-
-    Node* phi2 = R.Phi(a, b, a, a);
-    R.ReducePhi(phi2, phi2);
-
-    Node* phi3 = R.Phi(a, a, b, a);
-    R.ReducePhi(phi3, phi3);
-
-    Node* phi4 = R.Phi(a, a, a, b);
-    R.ReducePhi(phi4, phi4);
-  }
-}
-
-
-TEST(CReducePhi_iterative1) {
-  ControlReducerTester R;
-
-  R.ReducePhiIterative(R.leaf[0], R.Phi(R.leaf[0], R.Phi(R.leaf[0])));
-  R.ReducePhiIterative(R.leaf[0], R.Phi(R.Phi(R.leaf[0]), R.leaf[0]));
-}
-
-
-TEST(CReducePhi_iterative2) {
-  ControlReducerTester R;
-
-  R.ReducePhiIterative(R.leaf[0], R.Phi(R.Phi(R.leaf[0]), R.Phi(R.leaf[0])));
-}
-
-
-TEST(CReducePhi_iterative3) {
-  ControlReducerTester R;
-
-  R.ReducePhiIterative(R.leaf[0],
-                       R.Phi(R.leaf[0], R.Phi(R.leaf[0], R.leaf[0])));
-  R.ReducePhiIterative(R.leaf[0],
-                       R.Phi(R.Phi(R.leaf[0], R.leaf[0]), R.leaf[0]));
-}
-
-
-TEST(CReducePhi_iterative4) {
-  ControlReducerTester R;
-
-  R.ReducePhiIterative(R.leaf[0], R.Phi(R.Phi(R.leaf[0], R.leaf[0]),
-                                        R.Phi(R.leaf[0], R.leaf[0])));
-
-  Node* p1 = R.Phi(R.leaf[0], R.leaf[0]);
-  R.ReducePhiIterative(R.leaf[0], R.Phi(p1, p1));
-
-  Node* p2 = R.Phi(R.leaf[0], R.leaf[0], R.leaf[0]);
-  R.ReducePhiIterative(R.leaf[0], R.Phi(p2, p2, p2));
-
-  Node* p3 = R.Phi(R.leaf[0], R.leaf[0], R.leaf[0]);
-  R.ReducePhiIterative(R.leaf[0], R.Phi(p3, p3, R.leaf[0]));
-}
-
-
-TEST(CReducePhi_iterative_self1) {
-  ControlReducerTester R;
-
-  R.ReducePhiIterative(R.leaf[0], R.Phi(R.leaf[0], R.Phi(R.leaf[0], R.self)));
-  R.ReducePhiIterative(R.leaf[0], R.Phi(R.Phi(R.leaf[0], R.self), R.leaf[0]));
-}
-
-
-TEST(CReducePhi_iterative_self2) {
-  ControlReducerTester R;
-
-  R.ReducePhiIterative(
-      R.leaf[0], R.Phi(R.Phi(R.leaf[0], R.self), R.Phi(R.leaf[0], R.self)));
-  R.ReducePhiIterative(
-      R.leaf[0], R.Phi(R.Phi(R.self, R.leaf[0]), R.Phi(R.self, R.leaf[0])));
-
-  Node* p1 = R.Phi(R.leaf[0], R.self);
-  R.ReducePhiIterative(R.leaf[0], R.Phi(p1, p1));
-
-  Node* p2 = R.Phi(R.self, R.leaf[0]);
-  R.ReducePhiIterative(R.leaf[0], R.Phi(p2, p2));
-}
-
-
-TEST(EReducePhi1) {
-  ControlReducerTester R;
-
-  R.ReducePhi(R.leaf[0], R.EffectPhi(R.leaf[0]));
-  R.ReducePhi(R.leaf[1], R.EffectPhi(R.leaf[1]));
-  R.ReducePhi(R.leaf[2], R.EffectPhi(R.leaf[2]));
-  R.ReducePhi(R.leaf[3], R.EffectPhi(R.leaf[3]));
-}
-
-
-TEST(EReducePhi1_dead) {
-  ControlReducerTester R;
-
-  R.ReducePhi(R.leaf[0], R.EffectPhi(R.leaf[0], R.dead));
-  R.ReducePhi(R.leaf[1], R.EffectPhi(R.leaf[1], R.dead));
-  R.ReducePhi(R.leaf[2], R.EffectPhi(R.leaf[2], R.dead));
-  R.ReducePhi(R.leaf[3], R.EffectPhi(R.leaf[3], R.dead));
-
-  R.ReducePhi(R.leaf[0], R.EffectPhi(R.dead, R.leaf[0]));
-  R.ReducePhi(R.leaf[1], R.EffectPhi(R.dead, R.leaf[1]));
-  R.ReducePhi(R.leaf[2], R.EffectPhi(R.dead, R.leaf[2]));
-  R.ReducePhi(R.leaf[3], R.EffectPhi(R.dead, R.leaf[3]));
-}
-
-
-TEST(EReducePhi1_dead2) {
-  ControlReducerTester R;
-
-  R.ReducePhi(R.leaf[0], R.EffectPhi(R.leaf[0], R.dead, R.dead));
-  R.ReducePhi(R.leaf[0], R.EffectPhi(R.dead, R.leaf[0], R.dead));
-  R.ReducePhi(R.leaf[0], R.EffectPhi(R.dead, R.dead, R.leaf[0]));
-}
-
-
-TEST(CMergeReduce_simple1) {
-  ControlReducerTester R;
-
-  Node* merge = R.graph.NewNode(R.common.Merge(1), R.start);
-  R.ReduceMerge(R.start, merge);
-}
-
-
-TEST(CMergeReduce_simple2) {
-  ControlReducerTester R;
-
-  Node* merge1 = R.graph.NewNode(R.common.Merge(1), R.start);
-  Node* merge2 = R.graph.NewNode(R.common.Merge(1), merge1);
-  R.ReduceMerge(merge1, merge2);
-  R.ReduceMergeIterative(R.start, merge2);
-}
-
-
-TEST(CMergeReduce_none1) {
-  ControlReducerTester R;
-
-  Node* merge = R.graph.NewNode(R.common.Merge(2), R.start, R.start);
-  R.ReduceMerge(merge, merge);
-}
-
-
-TEST(CMergeReduce_none2) {
-  ControlReducerTester R;
-
-  Node* t = R.graph.NewNode(R.common.IfTrue(), R.start);
-  Node* f = R.graph.NewNode(R.common.IfFalse(), R.start);
-  Node* merge = R.graph.NewNode(R.common.Merge(2), t, f);
-  R.ReduceMerge(merge, merge);
-}
-
-
-TEST(CMergeReduce_self3) {
-  ControlReducerTester R;
-
-  Node* merge =
-      R.SetSelfReferences(R.graph.NewNode(R.common.Merge(2), R.start, R.self));
-  R.ReduceMerge(merge, merge);
-}
-
-
-TEST(CMergeReduce_dead1) {
-  ControlReducerTester R;
-
-  Node* merge = R.graph.NewNode(R.common.Merge(2), R.start, R.dead);
-  R.ReduceMerge(R.start, merge);
-}
-
-
-TEST(CMergeReduce_dead2) {
-  ControlReducerTester R;
-
-  Node* merge1 = R.graph.NewNode(R.common.Merge(1), R.start);
-  Node* merge2 = R.graph.NewNode(R.common.Merge(2), merge1, R.dead);
-  R.ReduceMerge(merge1, merge2);
-  R.ReduceMergeIterative(R.start, merge2);
-}
-
-
-TEST(CMergeReduce_dead_rm1a) {
-  ControlReducerTester R;
-
-  for (int i = 0; i < 3; i++) {
-    Node* merge = R.graph.NewNode(R.common.Merge(3), R.start, R.start, R.start);
-    merge->ReplaceInput(i, R.dead);
-    R.ReduceMerge(merge, merge);
-    CheckMerge(merge, R.start, R.start);
-  }
-}
-
-
-TEST(CMergeReduce_dead_rm1b) {
-  ControlReducerTester R;
-
-  Node* t = R.graph.NewNode(R.common.IfTrue(), R.start);
-  Node* f = R.graph.NewNode(R.common.IfFalse(), R.start);
-  for (int i = 0; i < 2; i++) {
-    Node* merge = R.graph.NewNode(R.common.Merge(3), R.dead, R.dead, R.dead);
-    for (int j = i + 1; j < 3; j++) {
-      merge->ReplaceInput(i, t);
-      merge->ReplaceInput(j, f);
-      R.ReduceMerge(merge, merge);
-      CheckMerge(merge, t, f);
-    }
-  }
-}
-
-
-TEST(CMergeReduce_dead_rm2) {
-  ControlReducerTester R;
-
-  for (int i = 0; i < 3; i++) {
-    Node* merge = R.graph.NewNode(R.common.Merge(3), R.dead, R.dead, R.dead);
-    merge->ReplaceInput(i, R.start);
-    R.ReduceMerge(R.start, merge);
-  }
-}
-
-
-TEST(CLoopReduce_dead_rm1) {
-  ControlReducerTester R;
-
-  for (int i = 0; i < 3; i++) {
-    Node* loop = R.graph.NewNode(R.common.Loop(3), R.dead, R.start, R.start);
-    R.ReduceMerge(loop, loop);
-    CheckLoop(loop, R.start, R.start);
-  }
-}
-
-
-TEST(CMergeReduce_edit_phi1) {
-  ControlReducerTester R;
-
-  for (int i = 0; i < 3; i++) {
-    Node* merge = R.graph.NewNode(R.common.Merge(3), R.start, R.start, R.start);
-    merge->ReplaceInput(i, R.dead);
-    Node* phi = R.graph.NewNode(R.common.Phi(kMachAnyTagged, 3), R.leaf[0],
-                                R.leaf[1], R.leaf[2], merge);
-    R.ReduceMerge(merge, merge);
-    CHECK_EQ(IrOpcode::kPhi, phi->opcode());
-    CHECK_EQ(2, phi->op()->ValueInputCount());
-    CHECK_EQ(3, phi->InputCount());
-    CHECK_EQ(R.leaf[i < 1 ? 1 : 0], phi->InputAt(0));
-    CHECK_EQ(R.leaf[i < 2 ? 2 : 1], phi->InputAt(1));
-    CHECK_EQ(merge, phi->InputAt(2));
-  }
-}
-
-
-TEST(CMergeReduce_edit_effect_phi1) {
-  ControlReducerTester R;
-
-  for (int i = 0; i < 3; i++) {
-    Node* merge = R.graph.NewNode(R.common.Merge(3), R.start, R.start, R.start);
-    merge->ReplaceInput(i, R.dead);
-    Node* phi = R.graph.NewNode(R.common.EffectPhi(3), R.leaf[0], R.leaf[1],
-                                R.leaf[2], merge);
-    R.ReduceMerge(merge, merge);
-    CHECK_EQ(IrOpcode::kEffectPhi, phi->opcode());
-    CHECK_EQ(0, phi->op()->ValueInputCount());
-    CHECK_EQ(2, phi->op()->EffectInputCount());
-    CHECK_EQ(3, phi->InputCount());
-    CHECK_EQ(R.leaf[i < 1 ? 1 : 0], phi->InputAt(0));
-    CHECK_EQ(R.leaf[i < 2 ? 2 : 1], phi->InputAt(1));
-    CHECK_EQ(merge, phi->InputAt(2));
-  }
-}
-
-
-static const int kSelectorSize = 4;
-
-// Helper to select K of N nodes according to a mask, useful for the test below.
-struct Selector {
-  int mask;
-  int count;
-  explicit Selector(int m) {
-    mask = m;
-    count = v8::base::bits::CountPopulation32(m);
-  }
-  bool is_selected(int i) { return (mask & (1 << i)) != 0; }
-  void CheckNode(Node* node, IrOpcode::Value opcode, Node** inputs,
-                 Node* control) {
-    CHECK_EQ(opcode, node->opcode());
-    CHECK_EQ(count + (control != NULL ? 1 : 0), node->InputCount());
-    int index = 0;
-    for (int i = 0; i < kSelectorSize; i++) {
-      if (mask & (1 << i)) {
-        CHECK_EQ(inputs[i], node->InputAt(index++));
-      }
-    }
-    CHECK_EQ(count, index);
-    if (control != NULL) CHECK_EQ(control, node->InputAt(index++));
-  }
-  int single_index() {
-    CHECK_EQ(1, count);
-    return WhichPowerOf2(mask);
-  }
-};
-
-
-TEST(CMergeReduce_exhaustive_4) {
-  ControlReducerTester R;
-  Node* controls[] = {
-      R.graph.NewNode(R.common.Start(1)), R.graph.NewNode(R.common.Start(2)),
-      R.graph.NewNode(R.common.Start(3)), R.graph.NewNode(R.common.Start(4))};
-  Node* values[] = {R.jsgraph.Int32Constant(11), R.jsgraph.Int32Constant(22),
-                    R.jsgraph.Int32Constant(33), R.jsgraph.Int32Constant(44)};
-  Node* effects[] = {
-      R.jsgraph.Float64Constant(123.4), R.jsgraph.Float64Constant(223.4),
-      R.jsgraph.Float64Constant(323.4), R.jsgraph.Float64Constant(423.4)};
-
-  for (int mask = 0; mask < (1 << (kSelectorSize - 1)); mask++) {
-    // Reduce a single merge with a given mask.
-    Node* merge = R.graph.NewNode(R.common.Merge(4), controls[0], controls[1],
-                                  controls[2], controls[3]);
-    Node* phi = R.graph.NewNode(R.common.Phi(kMachAnyTagged, 4), values[0],
-                                values[1], values[2], values[3], merge);
-    Node* ephi = R.graph.NewNode(R.common.EffectPhi(4), effects[0], effects[1],
-                                 effects[2], effects[3], merge);
-
-    Node* phi_use =
-        R.graph.NewNode(R.common.Phi(kMachAnyTagged, 1), phi, R.start);
-    Node* ephi_use = R.graph.NewNode(R.common.EffectPhi(1), ephi, R.start);
-
-    Selector selector(mask);
-
-    for (int i = 0; i < kSelectorSize; i++) {  // set up dead merge inputs.
-      if (!selector.is_selected(i)) merge->ReplaceInput(i, R.dead);
-    }
-
-    Node* result =
-        ControlReducer::ReduceMergeForTesting(&R.jsgraph, &R.common, merge);
-
-    int count = selector.count;
-    if (count == 0) {
-      // result should be dead.
-      CHECK_EQ(IrOpcode::kDead, result->opcode());
-    } else if (count == 1) {
-      // merge should be replaced with one of the controls.
-      CHECK_EQ(controls[selector.single_index()], result);
-      // Phis should have been directly replaced.
-      CHECK_EQ(values[selector.single_index()], phi_use->InputAt(0));
-      CHECK_EQ(effects[selector.single_index()], ephi_use->InputAt(0));
-    } else {
-      // Otherwise, nodes should be edited in place.
-      CHECK_EQ(merge, result);
-      selector.CheckNode(merge, IrOpcode::kMerge, controls, NULL);
-      selector.CheckNode(phi, IrOpcode::kPhi, values, merge);
-      selector.CheckNode(ephi, IrOpcode::kEffectPhi, effects, merge);
-      CHECK_EQ(phi, phi_use->InputAt(0));
-      CHECK_EQ(ephi, ephi_use->InputAt(0));
-      CHECK_EQ(count, phi->op()->ValueInputCount());
-      CHECK_EQ(count + 1, phi->InputCount());
-      CHECK_EQ(count, ephi->op()->EffectInputCount());
-      CHECK_EQ(count + 1, ephi->InputCount());
-    }
-  }
-}
-
-
-TEST(CMergeReduce_edit_many_phis1) {
-  ControlReducerTester R;
-
-  const int kPhiCount = 10;
-  Node* phis[kPhiCount];
-
-  for (int i = 0; i < 3; i++) {
-    Node* merge = R.graph.NewNode(R.common.Merge(3), R.start, R.start, R.start);
-    merge->ReplaceInput(i, R.dead);
-    for (int j = 0; j < kPhiCount; j++) {
-      phis[j] = R.graph.NewNode(R.common.Phi(kMachAnyTagged, 3), R.leaf[0],
-                                R.leaf[1], R.leaf[2], merge);
-    }
-    R.ReduceMerge(merge, merge);
-    for (int j = 0; j < kPhiCount; j++) {
-      Node* phi = phis[j];
-      CHECK_EQ(IrOpcode::kPhi, phi->opcode());
-      CHECK_EQ(2, phi->op()->ValueInputCount());
-      CHECK_EQ(3, phi->InputCount());
-      CHECK_EQ(R.leaf[i < 1 ? 1 : 0], phi->InputAt(0));
-      CHECK_EQ(R.leaf[i < 2 ? 2 : 1], phi->InputAt(1));
-      CHECK_EQ(merge, phi->InputAt(2));
-    }
-  }
-}
-
-
-TEST(CMergeReduce_simple_chain1) {
-  ControlReducerTester R;
-  for (int i = 0; i < 5; i++) {
-    Node* merge = R.graph.NewNode(R.common.Merge(1), R.start);
-    for (int j = 0; j < i; j++) {
-      merge = R.graph.NewNode(R.common.Merge(1), merge);
-    }
-    R.ReduceMergeIterative(R.start, merge);
-  }
-}
-
-
-TEST(CMergeReduce_dead_chain1) {
-  ControlReducerTester R;
-  for (int i = 0; i < 5; i++) {
-    Node* merge = R.graph.NewNode(R.common.Merge(1), R.dead);
-    for (int j = 0; j < i; j++) {
-      merge = R.graph.NewNode(R.common.Merge(1), merge);
-    }
-    Node* end = R.graph.NewNode(R.common.End(), merge);
-    R.graph.SetEnd(end);
-    R.ReduceGraph();
-    CHECK(merge->IsDead());
-    CHECK_EQ(NULL, end->InputAt(0));  // end dies.
-  }
-}
-
-
-TEST(CMergeReduce_dead_chain2) {
-  ControlReducerTester R;
-  for (int i = 0; i < 5; i++) {
-    Node* merge = R.graph.NewNode(R.common.Merge(1), R.start);
-    for (int j = 0; j < i; j++) {
-      merge = R.graph.NewNode(R.common.Merge(2), merge, R.dead);
-    }
-    R.ReduceMergeIterative(R.start, merge);
-  }
-}
-
-
-struct Branch {
-  Node* branch;
-  Node* if_true;
-  Node* if_false;
-
-  Branch(ControlReducerTester& R, Node* cond, Node* control = NULL) {
-    if (control == NULL) control = R.start;
-    branch = R.graph.NewNode(R.common.Branch(), cond, control);
-    if_true = R.graph.NewNode(R.common.IfTrue(), branch);
-    if_false = R.graph.NewNode(R.common.IfFalse(), branch);
-  }
-};
-
-
-// TODO(titzer): use the diamonds from src/compiler/diamond.h here.
-struct Diamond {
-  Node* branch;
-  Node* if_true;
-  Node* if_false;
-  Node* merge;
-  Node* phi;
-
-  Diamond(ControlReducerTester& R, Node* cond) {
-    branch = R.graph.NewNode(R.common.Branch(), cond, R.start);
-    if_true = R.graph.NewNode(R.common.IfTrue(), branch);
-    if_false = R.graph.NewNode(R.common.IfFalse(), branch);
-    merge = R.graph.NewNode(R.common.Merge(2), if_true, if_false);
-    phi = NULL;
-  }
-
-  Diamond(ControlReducerTester& R, Node* cond, Node* tv, Node* fv) {
-    branch = R.graph.NewNode(R.common.Branch(), cond, R.start);
-    if_true = R.graph.NewNode(R.common.IfTrue(), branch);
-    if_false = R.graph.NewNode(R.common.IfFalse(), branch);
-    merge = R.graph.NewNode(R.common.Merge(2), if_true, if_false);
-    phi = R.graph.NewNode(R.common.Phi(kMachAnyTagged, 2), tv, fv, merge);
-  }
-
-  void chain(Diamond& that) { branch->ReplaceInput(1, that.merge); }
-
-  // Nest {this} into either the if_true or if_false branch of {that}.
-  void nest(Diamond& that, bool if_true) {
-    if (if_true) {
-      branch->ReplaceInput(1, that.if_true);
-      that.merge->ReplaceInput(0, merge);
-    } else {
-      branch->ReplaceInput(1, that.if_false);
-      that.merge->ReplaceInput(1, merge);
-    }
-  }
-};
-
-
-struct While {
-  Node* branch;
-  Node* if_true;
-  Node* exit;
-  Node* loop;
-
-  While(ControlReducerTester& R, Node* cond) {
-    loop = R.graph.NewNode(R.common.Loop(2), R.start, R.start);
-    branch = R.graph.NewNode(R.common.Branch(), cond, loop);
-    if_true = R.graph.NewNode(R.common.IfTrue(), branch);
-    exit = R.graph.NewNode(R.common.IfFalse(), branch);
-    loop->ReplaceInput(1, if_true);
-  }
-
-  void chain(Node* control) { loop->ReplaceInput(0, control); }
-};
-
-
-TEST(CBranchReduce_none1) {
-  ControlReducerTester R;
-  Diamond d(R, R.p0);
-  R.ReduceBranch(d.branch, d.branch);
-}
-
-
-TEST(CBranchReduce_none2) {
-  ControlReducerTester R;
-  Diamond d1(R, R.p0);
-  Diamond d2(R, R.p0);
-  d2.chain(d1);
-  R.ReduceBranch(d2.branch, d2.branch);
-}
-
-
-TEST(CBranchReduce_true) {
-  ControlReducerTester R;
-  Node* true_values[] = {
-      R.one,                               R.jsgraph.Int32Constant(2),
-      R.jsgraph.Int32Constant(0x7fffffff), R.jsgraph.Constant(1.0),
-      R.jsgraph.Constant(22.1),            R.jsgraph.TrueConstant()};
-
-  for (size_t i = 0; i < arraysize(true_values); i++) {
-    Diamond d(R, true_values[i]);
-    Node* true_use = R.graph.NewNode(R.common.Merge(1), d.if_true);
-    Node* false_use = R.graph.NewNode(R.common.Merge(1), d.if_false);
-    R.ReduceBranch(R.start, d.branch);
-    CHECK_EQ(R.start, true_use->InputAt(0));
-    CHECK_EQ(IrOpcode::kDead, false_use->InputAt(0)->opcode());
-    CHECK(d.if_true->IsDead());   // replaced
-    CHECK(d.if_false->IsDead());  // replaced
-  }
-}
-
-
-TEST(CBranchReduce_false) {
-  ControlReducerTester R;
-  Node* false_values[] = {R.zero, R.jsgraph.Constant(0.0),
-                          R.jsgraph.Constant(-0.0), R.jsgraph.FalseConstant()};
-
-  for (size_t i = 0; i < arraysize(false_values); i++) {
-    Diamond d(R, false_values[i]);
-    Node* true_use = R.graph.NewNode(R.common.Merge(1), d.if_true);
-    Node* false_use = R.graph.NewNode(R.common.Merge(1), d.if_false);
-    R.ReduceBranch(R.start, d.branch);
-    CHECK_EQ(R.start, false_use->InputAt(0));
-    CHECK_EQ(IrOpcode::kDead, true_use->InputAt(0)->opcode());
-    CHECK(d.if_true->IsDead());   // replaced
-    CHECK(d.if_false->IsDead());  // replaced
-  }
-}
-
-
-TEST(CDiamondReduce_true) {
-  ControlReducerTester R;
-  Diamond d1(R, R.one);
-  R.ReduceMergeIterative(R.start, d1.merge);
-}
-
-
-TEST(CDiamondReduce_false) {
-  ControlReducerTester R;
-  Diamond d2(R, R.zero);
-  R.ReduceMergeIterative(R.start, d2.merge);
-}
-
-
-TEST(CChainedDiamondsReduce_true_false) {
-  ControlReducerTester R;
-  Diamond d1(R, R.one);
-  Diamond d2(R, R.zero);
-  d2.chain(d1);
-
-  R.ReduceMergeIterative(R.start, d2.merge);
-}
-
-
-TEST(CChainedDiamondsReduce_x_false) {
-  ControlReducerTester R;
-  Diamond d1(R, R.p0);
-  Diamond d2(R, R.zero);
-  d2.chain(d1);
-
-  R.ReduceMergeIterative(d1.merge, d2.merge);
-}
-
-
-TEST(CChainedDiamondsReduce_false_x) {
-  ControlReducerTester R;
-  Diamond d1(R, R.zero);
-  Diamond d2(R, R.p0);
-  d2.chain(d1);
-
-  R.ReduceMergeIterative(d2.merge, d2.merge);
-  CheckInputs(d2.branch, R.p0, R.start);
-}
-
-
-TEST(CChainedDiamondsReduce_phi1) {
-  ControlReducerTester R;
-  Diamond d1(R, R.zero, R.one, R.zero);  // foldable branch, phi.
-  Diamond d2(R, d1.phi);
-  d2.chain(d1);
-
-  R.ReduceMergeIterative(R.start, d2.merge);
-}
-
-
-TEST(CChainedDiamondsReduce_phi2) {
-  ControlReducerTester R;
-  Diamond d1(R, R.p0, R.one, R.one);  // redundant phi.
-  Diamond d2(R, d1.phi);
-  d2.chain(d1);
-
-  R.ReduceMergeIterative(d1.merge, d2.merge);
-}
-
-
-TEST(CNestedDiamondsReduce_true_true_false) {
-  ControlReducerTester R;
-  Diamond d1(R, R.one);
-  Diamond d2(R, R.zero);
-  d2.nest(d1, true);
-
-  R.ReduceMergeIterative(R.start, d1.merge);
-}
-
-
-TEST(CNestedDiamondsReduce_false_true_false) {
-  ControlReducerTester R;
-  Diamond d1(R, R.one);
-  Diamond d2(R, R.zero);
-  d2.nest(d1, false);
-
-  R.ReduceMergeIterative(R.start, d1.merge);
-}
-
-
-TEST(CNestedDiamonds_xyz) {
-  ControlReducerTester R;
-
-  for (int a = 0; a < 2; a++) {
-    for (int b = 0; b < 2; b++) {
-      for (int c = 0; c < 2; c++) {
-        Diamond d1(R, R.jsgraph.Int32Constant(a));
-        Diamond d2(R, R.jsgraph.Int32Constant(b));
-        d2.nest(d1, c);
-
-        R.ReduceMergeIterative(R.start, d1.merge);
-      }
-    }
-  }
-}
-
-
-TEST(CDeadLoop1) {
-  ControlReducerTester R;
-
-  Node* loop = R.graph.NewNode(R.common.Loop(1), R.start);
-  Branch b(R, R.p0, loop);
-  loop->ReplaceInput(0, b.if_true);  // loop is not connected to start.
-  Node* merge = R.graph.NewNode(R.common.Merge(2), R.start, b.if_false);
-  R.ReduceMergeIterative(R.start, merge);
-  CHECK(b.if_true->IsDead());
-  CHECK(b.if_false->IsDead());
-}
-
-
-TEST(CDeadLoop2) {
-  ControlReducerTester R;
-
-  While w(R, R.p0);
-  Diamond d(R, R.zero);
-  // if (0) { while (p0) ; } else { }
-  w.branch->ReplaceInput(1, d.if_true);
-  d.merge->ReplaceInput(0, w.exit);
-
-  R.ReduceMergeIterative(R.start, d.merge);
-  CHECK(d.if_true->IsDead());
-  CHECK(d.if_false->IsDead());
-}
-
-
-TEST(CNonTermLoop1) {
-  ControlReducerTester R;
-  Node* loop =
-      R.SetSelfReferences(R.graph.NewNode(R.common.Loop(2), R.start, R.self));
-  R.ReduceGraph();
-  Node* end = R.graph.end();
-  CheckLoop(loop, R.start, loop);
-  Node* merge = end->InputAt(0);
-  CheckMerge(merge, R.start, loop);
-}
-
-
-TEST(CNonTermLoop2) {
-  ControlReducerTester R;
-  Diamond d(R, R.p0);
-  Node* loop = R.SetSelfReferences(
-      R.graph.NewNode(R.common.Loop(2), d.if_false, R.self));
-  d.merge->ReplaceInput(1, R.dead);
-  Node* end = R.graph.end();
-  end->ReplaceInput(0, d.merge);
-  R.ReduceGraph();
-  CHECK_EQ(end, R.graph.end());
-  CheckLoop(loop, d.if_false, loop);
-  Node* merge = end->InputAt(0);
-  CheckMerge(merge, d.if_true, loop);
-}
-
-
-TEST(NonTermLoop3) {
-  ControlReducerTester R;
-  Node* loop = R.graph.NewNode(R.common.Loop(2), R.start, R.start);
-  Branch b(R, R.one, loop);
-  loop->ReplaceInput(1, b.if_true);
-  Node* end = R.graph.end();
-  end->ReplaceInput(0, b.if_false);
-
-  R.ReduceGraph();
-
-  CHECK_EQ(end, R.graph.end());
-  CheckInputs(end, loop);
-  CheckInputs(loop, R.start, loop);
-}
-
-
-TEST(CNonTermLoop_terminate1) {
-  ControlReducerTester R;
-  Node* loop = R.graph.NewNode(R.common.Loop(2), R.start, R.start);
-  Node* effect = R.SetSelfReferences(
-      R.graph.NewNode(R.common.EffectPhi(2), R.start, R.self, loop));
-  Branch b(R, R.one, loop);
-  loop->ReplaceInput(1, b.if_true);
-  Node* end = R.graph.end();
-  end->ReplaceInput(0, b.if_false);
-
-  R.ReduceGraph();
-
-  CHECK_EQ(end, R.graph.end());
-  CheckLoop(loop, R.start, loop);
-  Node* terminate = end->InputAt(0);
-  CHECK_EQ(IrOpcode::kTerminate, terminate->opcode());
-  CHECK_EQ(2, terminate->InputCount());
-  CHECK_EQ(1, terminate->op()->EffectInputCount());
-  CHECK_EQ(1, terminate->op()->ControlInputCount());
-  CheckInputs(terminate, effect, loop);
-}
-
-
-TEST(CNonTermLoop_terminate2) {
-  ControlReducerTester R;
-  Node* loop = R.graph.NewNode(R.common.Loop(2), R.start, R.start);
-  Node* effect1 = R.SetSelfReferences(
-      R.graph.NewNode(R.common.EffectPhi(2), R.start, R.self, loop));
-  Node* effect2 = R.SetSelfReferences(
-      R.graph.NewNode(R.common.EffectPhi(2), R.start, R.self, loop));
-  Branch b(R, R.one, loop);
-  loop->ReplaceInput(1, b.if_true);
-  Node* end = R.graph.end();
-  end->ReplaceInput(0, b.if_false);
-
-  R.ReduceGraph();
-
-  CheckLoop(loop, R.start, loop);
-  CHECK_EQ(end, R.graph.end());
-  Node* terminate = end->InputAt(0);
-  CHECK_EQ(IrOpcode::kTerminate, terminate->opcode());
-  CHECK_EQ(3, terminate->InputCount());
-  CHECK_EQ(2, terminate->op()->EffectInputCount());
-  CHECK_EQ(1, terminate->op()->ControlInputCount());
-  Node* e0 = terminate->InputAt(0);
-  Node* e1 = terminate->InputAt(1);
-  CHECK(e0 == effect1 || e1 == effect1);
-  CHECK(e0 == effect2 || e1 == effect2);
-  CHECK_EQ(loop, terminate->InputAt(2));
-}
-
-
-TEST(CNonTermLoop_terminate_m1) {
-  ControlReducerTester R;
-  Node* loop =
-      R.SetSelfReferences(R.graph.NewNode(R.common.Loop(2), R.start, R.self));
-  Node* effect = R.SetSelfReferences(
-      R.graph.NewNode(R.common.EffectPhi(2), R.start, R.self, loop));
-  R.ReduceGraph();
-  Node* end = R.graph.end();
-  CHECK_EQ(R.start, loop->InputAt(0));
-  CHECK_EQ(loop, loop->InputAt(1));
-  Node* merge = end->InputAt(0);
-  CHECK_EQ(IrOpcode::kMerge, merge->opcode());
-  CHECK_EQ(2, merge->InputCount());
-  CHECK_EQ(2, merge->op()->ControlInputCount());
-  CHECK_EQ(R.start, merge->InputAt(0));
-
-  Node* terminate = merge->InputAt(1);
-  CHECK_EQ(IrOpcode::kTerminate, terminate->opcode());
-  CHECK_EQ(2, terminate->InputCount());
-  CHECK_EQ(1, terminate->op()->EffectInputCount());
-  CHECK_EQ(1, terminate->op()->ControlInputCount());
-  CHECK_EQ(effect, terminate->InputAt(0));
-  CHECK_EQ(loop, terminate->InputAt(1));
-}
-
-
-TEST(CNonTermLoop_big1) {
-  ControlReducerTester R;
-  Branch b1(R, R.p0);
-  Node* rt = R.graph.NewNode(R.common.Return(), R.one, R.start, b1.if_true);
-
-  Branch b2(R, R.p0, b1.if_false);
-  Node* rf = R.graph.NewNode(R.common.Return(), R.zero, R.start, b2.if_true);
-  Node* loop = R.SetSelfReferences(
-      R.graph.NewNode(R.common.Loop(2), b2.if_false, R.self));
-  Node* merge = R.graph.NewNode(R.common.Merge(2), rt, rf);
-  R.end->ReplaceInput(0, merge);
-
-  R.ReduceGraph();
-
-  CheckInputs(R.end, merge);
-  CheckInputs(merge, rt, rf, loop);
-  CheckInputs(loop, b2.if_false, loop);
-}
-
-
-TEST(CNonTermLoop_big2) {
-  ControlReducerTester R;
-  Branch b1(R, R.p0);
-  Node* rt = R.graph.NewNode(R.common.Return(), R.one, R.start, b1.if_true);
-
-  Branch b2(R, R.zero, b1.if_false);
-  Node* rf = R.graph.NewNode(R.common.Return(), R.zero, R.start, b2.if_true);
-  Node* loop = R.SetSelfReferences(
-      R.graph.NewNode(R.common.Loop(2), b2.if_false, R.self));
-  Node* merge = R.graph.NewNode(R.common.Merge(2), rt, rf);
-  R.end->ReplaceInput(0, merge);
-
-  R.ReduceGraph();
-
-  Node* new_merge = R.end->InputAt(0);  // old merge was reduced.
-  CHECK_NE(merge, new_merge);
-  CheckInputs(new_merge, rt, loop);
-  CheckInputs(loop, b1.if_false, loop);
-  CHECK(merge->IsDead());
-  CHECK(rf->IsDead());
-  CHECK(b2.if_true->IsDead());
-}
-
-
-TEST(Return1) {
-  ControlReducerTester R;
-  Node* ret = R.Return(R.one, R.start, R.start);
-  R.ReduceGraph();
-  CheckInputs(R.graph.end(), ret);
-  CheckInputs(ret, R.one, R.start, R.start);
-}
-
-
-TEST(Return2) {
-  ControlReducerTester R;
-  Diamond d(R, R.one);
-  Node* ret = R.Return(R.half, R.start, d.merge);
-  R.ReduceGraph();
-  CHECK(d.branch->IsDead());
-  CHECK(d.if_true->IsDead());
-  CHECK(d.if_false->IsDead());
-  CHECK(d.merge->IsDead());
-
-  CheckInputs(R.graph.end(), ret);
-  CheckInputs(ret, R.half, R.start, R.start);
-}
-
-
-TEST(Return_true1) {
-  ControlReducerTester R;
-  Diamond d(R, R.one, R.half, R.zero);
-  Node* ret = R.Return(d.phi, R.start, d.merge);
-  R.ReduceGraph();
-  CHECK(d.branch->IsDead());
-  CHECK(d.if_true->IsDead());
-  CHECK(d.if_false->IsDead());
-  CHECK(d.merge->IsDead());
-  CHECK(d.phi->IsDead());
-
-  CheckInputs(R.graph.end(), ret);
-  CheckInputs(ret, R.half, R.start, R.start);
-}
-
-
-TEST(Return_false1) {
-  ControlReducerTester R;
-  Diamond d(R, R.zero, R.one, R.half);
-  Node* ret = R.Return(d.phi, R.start, d.merge);
-  R.ReduceGraph();
-  CHECK(d.branch->IsDead());
-  CHECK(d.if_true->IsDead());
-  CHECK(d.if_false->IsDead());
-  CHECK(d.merge->IsDead());
-  CHECK(d.phi->IsDead());
-
-  CheckInputs(R.graph.end(), ret);
-  CheckInputs(ret, R.half, R.start, R.start);
-}
-
-
-void CheckDeadDiamond(Diamond& d) {
-  CHECK(d.branch->IsDead());
-  CHECK(d.if_true->IsDead());
-  CHECK(d.if_false->IsDead());
-  CHECK(d.merge->IsDead());
-  if (d.phi != NULL) CHECK(d.phi->IsDead());
-}
-
-
-void CheckLiveDiamond(Diamond& d, bool live_phi = true) {
-  CheckInputs(d.merge, d.if_true, d.if_false);
-  CheckInputs(d.if_true, d.branch);
-  CheckInputs(d.if_false, d.branch);
-  if (d.phi != NULL) {
-    if (live_phi) {
-      CHECK_EQ(3, d.phi->InputCount());
-      CHECK_EQ(d.merge, d.phi->InputAt(2));
-    } else {
-      CHECK(d.phi->IsDead());
-    }
-  }
-}
-
-
-TEST(Return_effect1) {
-  ControlReducerTester R;
-  Diamond d(R, R.one);
-  Node* e1 = R.jsgraph.Float64Constant(-100.1);
-  Node* e2 = R.jsgraph.Float64Constant(+100.1);
-  Node* effect = R.graph.NewNode(R.common.EffectPhi(2), e1, e2, d.merge);
-  Node* ret = R.Return(R.p0, effect, d.merge);
-  R.ReduceGraph();
-  CheckDeadDiamond(d);
-  CHECK(effect->IsDead());
-
-  CheckInputs(R.graph.end(), ret);
-  CheckInputs(ret, R.p0, e1, R.start);
-}
-
-
-TEST(Return_nested_diamonds1) {
-  ControlReducerTester R;
-  Diamond d1(R, R.p0, R.one, R.zero);
-  Diamond d2(R, R.p0);
-  Diamond d3(R, R.p0);
-
-  d2.nest(d1, true);
-  d3.nest(d1, false);
-
-  Node* ret = R.Return(d1.phi, R.start, d1.merge);
-
-  R.ReduceGraph();  // nothing should happen.
-
-  CheckInputs(ret, d1.phi, R.start, d1.merge);
-  CheckInputs(d1.phi, R.one, R.zero, d1.merge);
-  CheckInputs(d1.merge, d2.merge, d3.merge);
-  CheckLiveDiamond(d2);
-  CheckLiveDiamond(d3);
-}
-
-
-TEST(Return_nested_diamonds_true1) {
-  ControlReducerTester R;
-  Diamond d1(R, R.one, R.one, R.zero);
-  Diamond d2(R, R.p0);
-  Diamond d3(R, R.p0);
-
-  d2.nest(d1, true);
-  d3.nest(d1, false);
-
-  Node* ret = R.Return(d1.phi, R.start, d1.merge);
-
-  R.ReduceGraph();  // d1 gets folded true.
-
-  CheckInputs(ret, R.one, R.start, d2.merge);
-  CheckInputs(d2.branch, R.p0, R.start);
-  CheckDeadDiamond(d1);
-  CheckLiveDiamond(d2);
-  CheckDeadDiamond(d3);
-}
-
-
-TEST(Return_nested_diamonds_false1) {
-  ControlReducerTester R;
-  Diamond d1(R, R.zero, R.one, R.zero);
-  Diamond d2(R, R.p0);
-  Diamond d3(R, R.p0);
-
-  d2.nest(d1, true);
-  d3.nest(d1, false);
-
-  Node* ret = R.Return(d1.phi, R.start, d1.merge);
-
-  R.ReduceGraph();  // d1 gets folded false.
-
-  CheckInputs(ret, R.zero, R.start, d3.merge);
-  CheckInputs(d3.branch, R.p0, R.start);
-  CheckDeadDiamond(d1);
-  CheckDeadDiamond(d2);
-  CheckLiveDiamond(d3);
-}
-
-
-TEST(Return_nested_diamonds_true_true1) {
-  ControlReducerTester R;
-  Diamond d1(R, R.one, R.one, R.zero);
-  Diamond d2(R, R.one);
-  Diamond d3(R, R.p0);
-
-  d2.nest(d1, true);
-  d3.nest(d1, false);
-
-  Node* ret = R.Return(d1.phi, R.start, d1.merge);
-
-  R.ReduceGraph();  // d1 and d2 both get folded true.
-
-  CheckInputs(ret, R.one, R.start, R.start);
-  CheckDeadDiamond(d1);
-  CheckDeadDiamond(d2);
-  CheckDeadDiamond(d3);
-}
-
-
-TEST(Return_nested_diamonds_true_false1) {
-  ControlReducerTester R;
-  Diamond d1(R, R.one, R.one, R.zero);
-  Diamond d2(R, R.zero);
-  Diamond d3(R, R.p0);
-
-  d2.nest(d1, true);
-  d3.nest(d1, false);
-
-  Node* ret = R.Return(d1.phi, R.start, d1.merge);
-
-  R.ReduceGraph();  // d1 gets folded true and d2 gets folded false.
-
-  CheckInputs(ret, R.one, R.start, R.start);
-  CheckDeadDiamond(d1);
-  CheckDeadDiamond(d2);
-  CheckDeadDiamond(d3);
-}
-
-
-TEST(Return_nested_diamonds2) {
-  ControlReducerTester R;
-  Node* x2 = R.jsgraph.Float64Constant(11.1);
-  Node* y2 = R.jsgraph.Float64Constant(22.2);
-  Node* x3 = R.jsgraph.Float64Constant(33.3);
-  Node* y3 = R.jsgraph.Float64Constant(44.4);
-
-  Diamond d2(R, R.p0, x2, y2);
-  Diamond d3(R, R.p0, x3, y3);
-  Diamond d1(R, R.p0, d2.phi, d3.phi);
-
-  d2.nest(d1, true);
-  d3.nest(d1, false);
-
-  Node* ret = R.Return(d1.phi, R.start, d1.merge);
-
-  R.ReduceGraph();  // nothing should happen.
-
-  CheckInputs(ret, d1.phi, R.start, d1.merge);
-  CheckInputs(d1.phi, d2.phi, d3.phi, d1.merge);
-  CheckInputs(d1.merge, d2.merge, d3.merge);
-  CheckLiveDiamond(d2);
-  CheckLiveDiamond(d3);
-}
-
-
-TEST(Return_nested_diamonds_true2) {
-  ControlReducerTester R;
-  Node* x2 = R.jsgraph.Float64Constant(11.1);
-  Node* y2 = R.jsgraph.Float64Constant(22.2);
-  Node* x3 = R.jsgraph.Float64Constant(33.3);
-  Node* y3 = R.jsgraph.Float64Constant(44.4);
-
-  Diamond d2(R, R.p0, x2, y2);
-  Diamond d3(R, R.p0, x3, y3);
-  Diamond d1(R, R.one, d2.phi, d3.phi);
-
-  d2.nest(d1, true);
-  d3.nest(d1, false);
-
-  Node* ret = R.Return(d1.phi, R.start, d1.merge);
-
-  R.ReduceGraph();  // d1 gets folded true.
-
-  CheckInputs(ret, d2.phi, R.start, d2.merge);
-  CheckInputs(d2.branch, R.p0, R.start);
-  CheckDeadDiamond(d1);
-  CheckLiveDiamond(d2);
-  CheckDeadDiamond(d3);
-}
-
-
-TEST(Return_nested_diamonds_true_true2) {
-  ControlReducerTester R;
-  Node* x2 = R.jsgraph.Float64Constant(11.1);
-  Node* y2 = R.jsgraph.Float64Constant(22.2);
-  Node* x3 = R.jsgraph.Float64Constant(33.3);
-  Node* y3 = R.jsgraph.Float64Constant(44.4);
-
-  Diamond d2(R, R.one, x2, y2);
-  Diamond d3(R, R.p0, x3, y3);
-  Diamond d1(R, R.one, d2.phi, d3.phi);
-
-  d2.nest(d1, true);
-  d3.nest(d1, false);
-
-  Node* ret = R.Return(d1.phi, R.start, d1.merge);
-
-  R.ReduceGraph();  // d1 gets folded true.
-
-  CheckInputs(ret, x2, R.start, R.start);
-  CheckDeadDiamond(d1);
-  CheckDeadDiamond(d2);
-  CheckDeadDiamond(d3);
-}
-
-
-TEST(Return_nested_diamonds_true_false2) {
-  ControlReducerTester R;
-  Node* x2 = R.jsgraph.Float64Constant(11.1);
-  Node* y2 = R.jsgraph.Float64Constant(22.2);
-  Node* x3 = R.jsgraph.Float64Constant(33.3);
-  Node* y3 = R.jsgraph.Float64Constant(44.4);
-
-  Diamond d2(R, R.zero, x2, y2);
-  Diamond d3(R, R.p0, x3, y3);
-  Diamond d1(R, R.one, d2.phi, d3.phi);
-
-  d2.nest(d1, true);
-  d3.nest(d1, false);
-
-  Node* ret = R.Return(d1.phi, R.start, d1.merge);
-
-  R.ReduceGraph();  // d1 gets folded true.
-
-  CheckInputs(ret, y2, R.start, R.start);
-  CheckDeadDiamond(d1);
-  CheckDeadDiamond(d2);
-  CheckDeadDiamond(d3);
-}
diff --git a/test/cctest/compiler/test-gap-resolver.cc b/test/cctest/compiler/test-gap-resolver.cc
index ea6f4ee..7f85088 100644
--- a/test/cctest/compiler/test-gap-resolver.cc
+++ b/test/cctest/compiler/test-gap-resolver.cc
@@ -7,19 +7,18 @@
 #include "src/base/utils/random-number-generator.h"
 #include "test/cctest/cctest.h"
 
-using namespace v8::internal;
-using namespace v8::internal::compiler;
+namespace v8 {
+namespace internal {
+namespace compiler {
 
 // The state of our move interpreter is the mapping of operands to values. Note
 // that the actual values don't really matter, all we care about is equality.
 class InterpreterState {
  public:
-  typedef std::vector<MoveOperands> Moves;
-
-  void ExecuteInParallel(Moves moves) {
+  void ExecuteInParallel(const ParallelMove* moves) {
     InterpreterState copy(*this);
-    for (Moves::iterator it = moves.begin(); it != moves.end(); ++it) {
-      if (!it->IsRedundant()) write(it->destination(), copy.read(it->source()));
+    for (const auto m : *moves) {
+      if (!m->IsRedundant()) write(m->destination(), copy.read(m->source()));
     }
   }
 
@@ -32,17 +31,41 @@
   }
 
  private:
+  struct Key {
+    bool is_constant;
+    bool is_float;
+    LocationOperand::LocationKind kind;
+    int index;
+
+    bool operator<(const Key& other) const {
+      if (this->is_constant != other.is_constant) {
+        return this->is_constant;
+      }
+      if (this->is_float != other.is_float) {
+        return this->is_float;
+      }
+      if (this->kind != other.kind) {
+        return this->kind < other.kind;
+      }
+      return this->index < other.index;
+    }
+
+    bool operator==(const Key& other) const {
+      return this->is_constant == other.is_constant &&
+             this->kind == other.kind && this->index == other.index;
+    }
+  };
+
   // Internally, the state is a normalized permutation of (kind,index) pairs.
-  typedef std::pair<InstructionOperand::Kind, int> Key;
   typedef Key Value;
   typedef std::map<Key, Value> OperandMap;
 
-  Value read(const InstructionOperand* op) const {
+  Value read(const InstructionOperand& op) const {
     OperandMap::const_iterator it = values_.find(KeyFor(op));
     return (it == values_.end()) ? ValueFor(op) : it->second;
   }
 
-  void write(const InstructionOperand* op, Value v) {
+  void write(const InstructionOperand& op, Value v) {
     if (v == ValueFor(op)) {
       values_.erase(KeyFor(op));
     } else {
@@ -50,12 +73,39 @@
     }
   }
 
-  static Key KeyFor(const InstructionOperand* op) {
-    return Key(op->kind(), op->index());
+  static Key KeyFor(const InstructionOperand& op) {
+    bool is_constant = op.IsConstant();
+    bool is_float = false;
+    LocationOperand::LocationKind kind;
+    int index;
+    if (!is_constant) {
+      if (op.IsRegister()) {
+        index = LocationOperand::cast(op).GetRegister().code();
+      } else if (op.IsDoubleRegister()) {
+        index = LocationOperand::cast(op).GetDoubleRegister().code();
+      } else {
+        index = LocationOperand::cast(op).index();
+      }
+      is_float = IsFloatingPoint(LocationOperand::cast(op).representation());
+      kind = LocationOperand::cast(op).location_kind();
+    } else {
+      index = ConstantOperand::cast(op).virtual_register();
+      kind = LocationOperand::REGISTER;
+    }
+    Key key = {is_constant, is_float, kind, index};
+    return key;
   }
 
-  static Value ValueFor(const InstructionOperand* op) {
-    return Value(op->kind(), op->index());
+  static Value ValueFor(const InstructionOperand& op) { return KeyFor(op); }
+
+  static InstructionOperand FromKey(Key key) {
+    if (key.is_constant) {
+      return ConstantOperand(key.index);
+    }
+    return AllocatedOperand(
+        key.kind,
+        v8::internal::compiler::InstructionSequence::DefaultRepresentation(),
+        key.index);
   }
 
   friend std::ostream& operator<<(std::ostream& os,
@@ -63,10 +113,12 @@
     for (OperandMap::const_iterator it = is.values_.begin();
          it != is.values_.end(); ++it) {
       if (it != is.values_.begin()) os << " ";
-      InstructionOperand source(it->first.first, it->first.second);
-      InstructionOperand destination(it->second.first, it->second.second);
-      MoveOperands mo(&source, &destination);
-      PrintableMoveOperands pmo = {RegisterConfiguration::ArchDefault(), &mo};
+      InstructionOperand source = FromKey(it->first);
+      InstructionOperand destination = FromKey(it->second);
+      MoveOperands mo(source, destination);
+      PrintableMoveOperands pmo = {
+          RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN),
+          &mo};
       os << pmo;
     }
     return os;
@@ -79,30 +131,31 @@
 // An abstract interpreter for moves, swaps and parallel moves.
 class MoveInterpreter : public GapResolver::Assembler {
  public:
-  virtual void AssembleMove(InstructionOperand* source,
-                            InstructionOperand* destination) OVERRIDE {
-    InterpreterState::Moves moves;
-    moves.push_back(MoveOperands(source, destination));
+  explicit MoveInterpreter(Zone* zone) : zone_(zone) {}
+
+  void AssembleMove(InstructionOperand* source,
+                    InstructionOperand* destination) override {
+    ParallelMove* moves = new (zone_) ParallelMove(zone_);
+    moves->AddMove(*source, *destination);
     state_.ExecuteInParallel(moves);
   }
 
-  virtual void AssembleSwap(InstructionOperand* source,
-                            InstructionOperand* destination) OVERRIDE {
-    InterpreterState::Moves moves;
-    moves.push_back(MoveOperands(source, destination));
-    moves.push_back(MoveOperands(destination, source));
+  void AssembleSwap(InstructionOperand* source,
+                    InstructionOperand* destination) override {
+    ParallelMove* moves = new (zone_) ParallelMove(zone_);
+    moves->AddMove(*source, *destination);
+    moves->AddMove(*destination, *source);
     state_.ExecuteInParallel(moves);
   }
 
-  void AssembleParallelMove(const ParallelMove* pm) {
-    InterpreterState::Moves moves(pm->move_operands()->begin(),
-                                  pm->move_operands()->end());
+  void AssembleParallelMove(const ParallelMove* moves) {
     state_.ExecuteInParallel(moves);
   }
 
   InterpreterState state() const { return state_; }
 
  private:
+  Zone* const zone_;
   InterpreterState state_;
 };
 
@@ -113,11 +166,11 @@
 
   ParallelMove* Create(int size) {
     ParallelMove* parallel_move = new (main_zone()) ParallelMove(main_zone());
-    std::set<InstructionOperand*, InstructionOperandComparator> seen;
+    std::set<InstructionOperand, CompareOperandModuloType> seen;
     for (int i = 0; i < size; ++i) {
-      MoveOperands mo(CreateRandomOperand(), CreateRandomOperand());
+      MoveOperands mo(CreateRandomOperand(true), CreateRandomOperand(false));
       if (!mo.IsRedundant() && seen.find(mo.destination()) == seen.end()) {
-        parallel_move->AddMove(mo.source(), mo.destination(), main_zone());
+        parallel_move->AddMove(mo.source(), mo.destination());
         seen.insert(mo.destination());
       }
     }
@@ -125,30 +178,57 @@
   }
 
  private:
-  struct InstructionOperandComparator {
-    bool operator()(const InstructionOperand* x,
-                    const InstructionOperand* y) const {
-      return (x->kind() < y->kind()) ||
-             (x->kind() == y->kind() && x->index() < y->index());
-    }
-  };
-
-  InstructionOperand* CreateRandomOperand() {
-    int index = rng_->NextInt(6);
-    switch (rng_->NextInt(5)) {
+  MachineRepresentation RandomRepresentation() {
+    int index = rng_->NextInt(3);
+    switch (index) {
       case 0:
-        return ConstantOperand::Create(index, main_zone());
+        return MachineRepresentation::kWord32;
       case 1:
-        return StackSlotOperand::Create(index, main_zone());
+        return MachineRepresentation::kWord64;
       case 2:
-        return DoubleStackSlotOperand::Create(index, main_zone());
-      case 3:
-        return RegisterOperand::Create(index, main_zone());
-      case 4:
-        return DoubleRegisterOperand::Create(index, main_zone());
+        return MachineRepresentation::kTagged;
     }
     UNREACHABLE();
-    return NULL;
+    return MachineRepresentation::kNone;
+  }
+
+  MachineRepresentation RandomDoubleRepresentation() {
+    int index = rng_->NextInt(2);
+    if (index == 0) return MachineRepresentation::kFloat64;
+    return MachineRepresentation::kFloat32;
+  }
+
+  InstructionOperand CreateRandomOperand(bool is_source) {
+    int index = rng_->NextInt(7);
+    // destination can't be Constant.
+    switch (rng_->NextInt(is_source ? 7 : 6)) {
+      case 0:
+        return AllocatedOperand(LocationOperand::STACK_SLOT,
+                                RandomRepresentation(), index);
+      case 1:
+        return AllocatedOperand(LocationOperand::STACK_SLOT,
+                                RandomDoubleRepresentation(), index);
+      case 2:
+        return AllocatedOperand(LocationOperand::REGISTER,
+                                RandomRepresentation(), index);
+      case 3:
+        return AllocatedOperand(LocationOperand::REGISTER,
+                                RandomDoubleRepresentation(), index);
+      case 4:
+        return ExplicitOperand(
+            LocationOperand::REGISTER, RandomRepresentation(),
+            RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN)
+                ->GetAllocatableGeneralCode(1));
+      case 5:
+        return ExplicitOperand(
+            LocationOperand::STACK_SLOT, RandomRepresentation(),
+            RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN)
+                ->GetAllocatableGeneralCode(index));
+      case 6:
+        return ConstantOperand(index);
+    }
+    UNREACHABLE();
+    return InstructionOperand();
   }
 
  private:
@@ -163,10 +243,10 @@
       ParallelMove* pm = pmc.Create(size);
 
       // Note: The gap resolver modifies the ParallelMove, so interpret first.
-      MoveInterpreter mi1;
+      MoveInterpreter mi1(pmc.main_zone());
       mi1.AssembleParallelMove(pm);
 
-      MoveInterpreter mi2;
+      MoveInterpreter mi2(pmc.main_zone());
       GapResolver resolver(&mi2);
       resolver.Resolve(pm);
 
@@ -174,3 +254,7 @@
     }
   }
 }
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/test/cctest/compiler/test-graph-reducer.cc b/test/cctest/compiler/test-graph-reducer.cc
deleted file mode 100644
index 70b57b9..0000000
--- a/test/cctest/compiler/test-graph-reducer.cc
+++ /dev/null
@@ -1,622 +0,0 @@
-// Copyright 2014 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "src/v8.h"
-
-#include "graph-tester.h"
-#include "src/compiler/graph-reducer.h"
-
-using namespace v8::internal;
-using namespace v8::internal::compiler;
-
-const uint8_t OPCODE_A0 = 10;
-const uint8_t OPCODE_A1 = 11;
-const uint8_t OPCODE_A2 = 12;
-const uint8_t OPCODE_B0 = 20;
-const uint8_t OPCODE_B1 = 21;
-const uint8_t OPCODE_B2 = 22;
-const uint8_t OPCODE_C0 = 30;
-const uint8_t OPCODE_C1 = 31;
-const uint8_t OPCODE_C2 = 32;
-
-static Operator OPA0(OPCODE_A0, Operator::kNoWrite, "opa0", 0, 0, 0, 0, 0, 0);
-static Operator OPA1(OPCODE_A1, Operator::kNoWrite, "opa1", 1, 0, 0, 0, 0, 0);
-static Operator OPA2(OPCODE_A2, Operator::kNoWrite, "opa2", 2, 0, 0, 0, 0, 0);
-static Operator OPB0(OPCODE_B0, Operator::kNoWrite, "opa0", 0, 0, 0, 0, 0, 0);
-static Operator OPB1(OPCODE_B1, Operator::kNoWrite, "opa1", 1, 0, 0, 0, 0, 0);
-static Operator OPB2(OPCODE_B2, Operator::kNoWrite, "opa2", 2, 0, 0, 0, 0, 0);
-static Operator OPC0(OPCODE_C0, Operator::kNoWrite, "opc0", 0, 0, 0, 0, 0, 0);
-static Operator OPC1(OPCODE_C1, Operator::kNoWrite, "opc1", 1, 0, 0, 0, 0, 0);
-static Operator OPC2(OPCODE_C2, Operator::kNoWrite, "opc2", 2, 0, 0, 0, 0, 0);
-
-
-// Replaces all "A" operators with "B" operators without creating new nodes.
-class InPlaceABReducer : public Reducer {
- public:
-  virtual Reduction Reduce(Node* node) {
-    switch (node->op()->opcode()) {
-      case OPCODE_A0:
-        CHECK_EQ(0, node->InputCount());
-        node->set_op(&OPB0);
-        return Replace(node);
-      case OPCODE_A1:
-        CHECK_EQ(1, node->InputCount());
-        node->set_op(&OPB1);
-        return Replace(node);
-      case OPCODE_A2:
-        CHECK_EQ(2, node->InputCount());
-        node->set_op(&OPB2);
-        return Replace(node);
-    }
-    return NoChange();
-  }
-};
-
-
-// Replaces all "A" operators with "B" operators by allocating new nodes.
-class NewABReducer : public Reducer {
- public:
-  explicit NewABReducer(Graph* graph) : graph_(graph) {}
-  virtual Reduction Reduce(Node* node) {
-    switch (node->op()->opcode()) {
-      case OPCODE_A0:
-        CHECK_EQ(0, node->InputCount());
-        return Replace(graph_->NewNode(&OPB0));
-      case OPCODE_A1:
-        CHECK_EQ(1, node->InputCount());
-        return Replace(graph_->NewNode(&OPB1, node->InputAt(0)));
-      case OPCODE_A2:
-        CHECK_EQ(2, node->InputCount());
-        return Replace(
-            graph_->NewNode(&OPB2, node->InputAt(0), node->InputAt(1)));
-    }
-    return NoChange();
-  }
-  Graph* graph_;
-};
-
-
-// Replaces all "B" operators with "C" operators without creating new nodes.
-class InPlaceBCReducer : public Reducer {
- public:
-  virtual Reduction Reduce(Node* node) {
-    switch (node->op()->opcode()) {
-      case OPCODE_B0:
-        CHECK_EQ(0, node->InputCount());
-        node->set_op(&OPC0);
-        return Replace(node);
-      case OPCODE_B1:
-        CHECK_EQ(1, node->InputCount());
-        node->set_op(&OPC1);
-        return Replace(node);
-      case OPCODE_B2:
-        CHECK_EQ(2, node->InputCount());
-        node->set_op(&OPC2);
-        return Replace(node);
-    }
-    return NoChange();
-  }
-};
-
-
-// Wraps all "OPA0" nodes in "OPB1" operators by allocating new nodes.
-class A0Wrapper FINAL : public Reducer {
- public:
-  explicit A0Wrapper(Graph* graph) : graph_(graph) {}
-  virtual Reduction Reduce(Node* node) OVERRIDE {
-    switch (node->op()->opcode()) {
-      case OPCODE_A0:
-        CHECK_EQ(0, node->InputCount());
-        return Replace(graph_->NewNode(&OPB1, node));
-    }
-    return NoChange();
-  }
-  Graph* graph_;
-};
-
-
-// Wraps all "OPB0" nodes in two "OPC1" operators by allocating new nodes.
-class B0Wrapper FINAL : public Reducer {
- public:
-  explicit B0Wrapper(Graph* graph) : graph_(graph) {}
-  virtual Reduction Reduce(Node* node) OVERRIDE {
-    switch (node->op()->opcode()) {
-      case OPCODE_B0:
-        CHECK_EQ(0, node->InputCount());
-        return Replace(graph_->NewNode(&OPC1, graph_->NewNode(&OPC1, node)));
-    }
-    return NoChange();
-  }
-  Graph* graph_;
-};
-
-
-// Replaces all "OPA1" nodes with the first input.
-class A1Forwarder : public Reducer {
-  virtual Reduction Reduce(Node* node) {
-    switch (node->op()->opcode()) {
-      case OPCODE_A1:
-        CHECK_EQ(1, node->InputCount());
-        return Replace(node->InputAt(0));
-    }
-    return NoChange();
-  }
-};
-
-
-// Replaces all "OPB1" nodes with the first input.
-class B1Forwarder : public Reducer {
-  virtual Reduction Reduce(Node* node) {
-    switch (node->op()->opcode()) {
-      case OPCODE_B1:
-        CHECK_EQ(1, node->InputCount());
-        return Replace(node->InputAt(0));
-    }
-    return NoChange();
-  }
-};
-
-
-// Swaps the inputs to "OP2A" and "OP2B" nodes based on ids.
-class AB2Sorter : public Reducer {
-  virtual Reduction Reduce(Node* node) {
-    switch (node->op()->opcode()) {
-      case OPCODE_A2:
-      case OPCODE_B2:
-        CHECK_EQ(2, node->InputCount());
-        Node* x = node->InputAt(0);
-        Node* y = node->InputAt(1);
-        if (x->id() > y->id()) {
-          node->ReplaceInput(0, y);
-          node->ReplaceInput(1, x);
-          return Replace(node);
-        }
-    }
-    return NoChange();
-  }
-};
-
-
-// Simply records the nodes visited.
-class ReducerRecorder : public Reducer {
- public:
-  explicit ReducerRecorder(Zone* zone)
-      : set(NodeSet::key_compare(), NodeSet::allocator_type(zone)) {}
-  virtual Reduction Reduce(Node* node) {
-    set.insert(node);
-    return NoChange();
-  }
-  void CheckContains(Node* node) {
-    CHECK_EQ(1, static_cast<int>(set.count(node)));
-  }
-  NodeSet set;
-};
-
-
-TEST(ReduceGraphFromEnd1) {
-  GraphTester graph;
-
-  Node* n1 = graph.NewNode(&OPA0);
-  Node* end = graph.NewNode(&OPA1, n1);
-  graph.SetEnd(end);
-
-  GraphReducer reducer(&graph, graph.zone());
-  ReducerRecorder recorder(graph.zone());
-  reducer.AddReducer(&recorder);
-  reducer.ReduceGraph();
-  recorder.CheckContains(n1);
-  recorder.CheckContains(end);
-}
-
-
-TEST(ReduceGraphFromEnd2) {
-  GraphTester graph;
-
-  Node* n1 = graph.NewNode(&OPA0);
-  Node* n2 = graph.NewNode(&OPA1, n1);
-  Node* n3 = graph.NewNode(&OPA1, n1);
-  Node* end = graph.NewNode(&OPA2, n2, n3);
-  graph.SetEnd(end);
-
-  GraphReducer reducer(&graph, graph.zone());
-  ReducerRecorder recorder(graph.zone());
-  reducer.AddReducer(&recorder);
-  reducer.ReduceGraph();
-  recorder.CheckContains(n1);
-  recorder.CheckContains(n2);
-  recorder.CheckContains(n3);
-  recorder.CheckContains(end);
-}
-
-
-TEST(ReduceInPlace1) {
-  GraphTester graph;
-
-  Node* n1 = graph.NewNode(&OPA0);
-  Node* end = graph.NewNode(&OPA1, n1);
-  graph.SetEnd(end);
-
-  GraphReducer reducer(&graph, graph.zone());
-  InPlaceABReducer r;
-  reducer.AddReducer(&r);
-
-  // Tests A* => B* with in-place updates.
-  for (int i = 0; i < 3; i++) {
-    int before = graph.NodeCount();
-    reducer.ReduceGraph();
-    CHECK_EQ(before, graph.NodeCount());
-    CHECK_EQ(&OPB0, n1->op());
-    CHECK_EQ(&OPB1, end->op());
-    CHECK_EQ(n1, end->InputAt(0));
-  }
-}
-
-
-TEST(ReduceInPlace2) {
-  GraphTester graph;
-
-  Node* n1 = graph.NewNode(&OPA0);
-  Node* n2 = graph.NewNode(&OPA1, n1);
-  Node* n3 = graph.NewNode(&OPA1, n1);
-  Node* end = graph.NewNode(&OPA2, n2, n3);
-  graph.SetEnd(end);
-
-  GraphReducer reducer(&graph, graph.zone());
-  InPlaceABReducer r;
-  reducer.AddReducer(&r);
-
-  // Tests A* => B* with in-place updates.
-  for (int i = 0; i < 3; i++) {
-    int before = graph.NodeCount();
-    reducer.ReduceGraph();
-    CHECK_EQ(before, graph.NodeCount());
-    CHECK_EQ(&OPB0, n1->op());
-    CHECK_EQ(&OPB1, n2->op());
-    CHECK_EQ(n1, n2->InputAt(0));
-    CHECK_EQ(&OPB1, n3->op());
-    CHECK_EQ(n1, n3->InputAt(0));
-    CHECK_EQ(&OPB2, end->op());
-    CHECK_EQ(n2, end->InputAt(0));
-    CHECK_EQ(n3, end->InputAt(1));
-  }
-}
-
-
-TEST(ReduceNew1) {
-  GraphTester graph;
-
-  Node* n1 = graph.NewNode(&OPA0);
-  Node* n2 = graph.NewNode(&OPA1, n1);
-  Node* n3 = graph.NewNode(&OPA1, n1);
-  Node* end = graph.NewNode(&OPA2, n2, n3);
-  graph.SetEnd(end);
-
-  GraphReducer reducer(&graph, graph.zone());
-  NewABReducer r(&graph);
-  reducer.AddReducer(&r);
-
-  // Tests A* => B* while creating new nodes.
-  for (int i = 0; i < 3; i++) {
-    int before = graph.NodeCount();
-    reducer.ReduceGraph();
-    if (i == 0) {
-      CHECK_NE(before, graph.NodeCount());
-    } else {
-      CHECK_EQ(before, graph.NodeCount());
-    }
-    Node* nend = graph.end();
-    CHECK_NE(end, nend);  // end() should be updated too.
-
-    Node* nn2 = nend->InputAt(0);
-    Node* nn3 = nend->InputAt(1);
-    Node* nn1 = nn2->InputAt(0);
-
-    CHECK_EQ(nn1, nn3->InputAt(0));
-
-    CHECK_EQ(&OPB0, nn1->op());
-    CHECK_EQ(&OPB1, nn2->op());
-    CHECK_EQ(&OPB1, nn3->op());
-    CHECK_EQ(&OPB2, nend->op());
-  }
-}
-
-
-TEST(Wrapping1) {
-  GraphTester graph;
-
-  Node* end = graph.NewNode(&OPA0);
-  graph.SetEnd(end);
-  CHECK_EQ(1, graph.NodeCount());
-
-  GraphReducer reducer(&graph, graph.zone());
-  A0Wrapper r(&graph);
-  reducer.AddReducer(&r);
-
-  reducer.ReduceGraph();
-  CHECK_EQ(2, graph.NodeCount());
-
-  Node* nend = graph.end();
-  CHECK_NE(end, nend);
-  CHECK_EQ(&OPB1, nend->op());
-  CHECK_EQ(1, nend->InputCount());
-  CHECK_EQ(end, nend->InputAt(0));
-}
-
-
-TEST(Wrapping2) {
-  GraphTester graph;
-
-  Node* end = graph.NewNode(&OPB0);
-  graph.SetEnd(end);
-  CHECK_EQ(1, graph.NodeCount());
-
-  GraphReducer reducer(&graph, graph.zone());
-  B0Wrapper r(&graph);
-  reducer.AddReducer(&r);
-
-  reducer.ReduceGraph();
-  CHECK_EQ(3, graph.NodeCount());
-
-  Node* nend = graph.end();
-  CHECK_NE(end, nend);
-  CHECK_EQ(&OPC1, nend->op());
-  CHECK_EQ(1, nend->InputCount());
-
-  Node* n1 = nend->InputAt(0);
-  CHECK_NE(end, n1);
-  CHECK_EQ(&OPC1, n1->op());
-  CHECK_EQ(1, n1->InputCount());
-  CHECK_EQ(end, n1->InputAt(0));
-}
-
-
-TEST(Forwarding1) {
-  GraphTester graph;
-
-  Node* n1 = graph.NewNode(&OPA0);
-  Node* end = graph.NewNode(&OPA1, n1);
-  graph.SetEnd(end);
-
-  GraphReducer reducer(&graph, graph.zone());
-  A1Forwarder r;
-  reducer.AddReducer(&r);
-
-  // Tests A1(x) => x
-  for (int i = 0; i < 3; i++) {
-    int before = graph.NodeCount();
-    reducer.ReduceGraph();
-    CHECK_EQ(before, graph.NodeCount());
-    CHECK_EQ(&OPA0, n1->op());
-    CHECK_EQ(n1, graph.end());
-  }
-}
-
-
-TEST(Forwarding2) {
-  GraphTester graph;
-
-  Node* n1 = graph.NewNode(&OPA0);
-  Node* n2 = graph.NewNode(&OPA1, n1);
-  Node* n3 = graph.NewNode(&OPA1, n1);
-  Node* end = graph.NewNode(&OPA2, n2, n3);
-  graph.SetEnd(end);
-
-  GraphReducer reducer(&graph, graph.zone());
-  A1Forwarder r;
-  reducer.AddReducer(&r);
-
-  // Tests reducing A2(A1(x), A1(y)) => A2(x, y).
-  for (int i = 0; i < 3; i++) {
-    int before = graph.NodeCount();
-    reducer.ReduceGraph();
-    CHECK_EQ(before, graph.NodeCount());
-    CHECK_EQ(&OPA0, n1->op());
-    CHECK_EQ(n1, end->InputAt(0));
-    CHECK_EQ(n1, end->InputAt(1));
-    CHECK_EQ(&OPA2, end->op());
-    CHECK_EQ(0, n2->UseCount());
-    CHECK_EQ(0, n3->UseCount());
-  }
-}
-
-
-TEST(Forwarding3) {
-  // Tests reducing a chain of A1(A1(A1(A1(x)))) => x.
-  for (int i = 0; i < 8; i++) {
-    GraphTester graph;
-
-    Node* n1 = graph.NewNode(&OPA0);
-    Node* end = n1;
-    for (int j = 0; j < i; j++) {
-      end = graph.NewNode(&OPA1, end);
-    }
-    graph.SetEnd(end);
-
-    GraphReducer reducer(&graph, graph.zone());
-    A1Forwarder r;
-    reducer.AddReducer(&r);
-
-    for (int i = 0; i < 3; i++) {
-      int before = graph.NodeCount();
-      reducer.ReduceGraph();
-      CHECK_EQ(before, graph.NodeCount());
-      CHECK_EQ(&OPA0, n1->op());
-      CHECK_EQ(n1, graph.end());
-    }
-  }
-}
-
-
-TEST(ReduceForward1) {
-  GraphTester graph;
-
-  Node* n1 = graph.NewNode(&OPA0);
-  Node* n2 = graph.NewNode(&OPA1, n1);
-  Node* n3 = graph.NewNode(&OPA1, n1);
-  Node* end = graph.NewNode(&OPA2, n2, n3);
-  graph.SetEnd(end);
-
-  GraphReducer reducer(&graph, graph.zone());
-  InPlaceABReducer r;
-  B1Forwarder f;
-  reducer.AddReducer(&r);
-  reducer.AddReducer(&f);
-
-  // Tests first reducing A => B, then B1(x) => x.
-  for (int i = 0; i < 3; i++) {
-    int before = graph.NodeCount();
-    reducer.ReduceGraph();
-    CHECK_EQ(before, graph.NodeCount());
-    CHECK_EQ(&OPB0, n1->op());
-    CHECK(n2->IsDead());
-    CHECK_EQ(n1, end->InputAt(0));
-    CHECK(n3->IsDead());
-    CHECK_EQ(n1, end->InputAt(0));
-    CHECK_EQ(&OPB2, end->op());
-    CHECK_EQ(0, n2->UseCount());
-    CHECK_EQ(0, n3->UseCount());
-  }
-}
-
-
-TEST(Sorter1) {
-  HandleAndZoneScope scope;
-  AB2Sorter r;
-  for (int i = 0; i < 6; i++) {
-    GraphTester graph;
-
-    Node* n1 = graph.NewNode(&OPA0);
-    Node* n2 = graph.NewNode(&OPA1, n1);
-    Node* n3 = graph.NewNode(&OPA1, n1);
-    Node* end = NULL;  // Initialize to please the compiler.
-
-    if (i == 0) end = graph.NewNode(&OPA2, n2, n3);
-    if (i == 1) end = graph.NewNode(&OPA2, n3, n2);
-    if (i == 2) end = graph.NewNode(&OPA2, n2, n1);
-    if (i == 3) end = graph.NewNode(&OPA2, n1, n2);
-    if (i == 4) end = graph.NewNode(&OPA2, n3, n1);
-    if (i == 5) end = graph.NewNode(&OPA2, n1, n3);
-
-    graph.SetEnd(end);
-
-    GraphReducer reducer(&graph, graph.zone());
-    reducer.AddReducer(&r);
-
-    int before = graph.NodeCount();
-    reducer.ReduceGraph();
-    CHECK_EQ(before, graph.NodeCount());
-    CHECK_EQ(&OPA0, n1->op());
-    CHECK_EQ(&OPA1, n2->op());
-    CHECK_EQ(&OPA1, n3->op());
-    CHECK_EQ(&OPA2, end->op());
-    CHECK_EQ(end, graph.end());
-    CHECK(end->InputAt(0)->id() <= end->InputAt(1)->id());
-  }
-}
-
-
-// Generate a node graph with the given permutations.
-void GenDAG(Graph* graph, int* p3, int* p2, int* p1) {
-  Node* level4 = graph->NewNode(&OPA0);
-  Node* level3[] = {graph->NewNode(&OPA1, level4),
-                    graph->NewNode(&OPA1, level4)};
-
-  Node* level2[] = {graph->NewNode(&OPA1, level3[p3[0]]),
-                    graph->NewNode(&OPA1, level3[p3[1]]),
-                    graph->NewNode(&OPA1, level3[p3[0]]),
-                    graph->NewNode(&OPA1, level3[p3[1]])};
-
-  Node* level1[] = {graph->NewNode(&OPA2, level2[p2[0]], level2[p2[1]]),
-                    graph->NewNode(&OPA2, level2[p2[2]], level2[p2[3]])};
-
-  Node* end = graph->NewNode(&OPA2, level1[p1[0]], level1[p1[1]]);
-  graph->SetEnd(end);
-}
-
-
-TEST(SortForwardReduce) {
-  GraphTester graph;
-
-  // Tests combined reductions on a series of DAGs.
-  for (int j = 0; j < 2; j++) {
-    int p3[] = {j, 1 - j};
-    for (int m = 0; m < 2; m++) {
-      int p1[] = {m, 1 - m};
-      for (int k = 0; k < 24; k++) {  // All permutations of 0, 1, 2, 3
-        int p2[] = {-1, -1, -1, -1};
-        int n = k;
-        for (int d = 4; d >= 1; d--) {  // Construct permutation.
-          int p = n % d;
-          for (int z = 0; z < 4; z++) {
-            if (p2[z] == -1) {
-              if (p == 0) p2[z] = d - 1;
-              p--;
-            }
-          }
-          n = n / d;
-        }
-
-        GenDAG(&graph, p3, p2, p1);
-
-        GraphReducer reducer(&graph, graph.zone());
-        AB2Sorter r1;
-        A1Forwarder r2;
-        InPlaceABReducer r3;
-        reducer.AddReducer(&r1);
-        reducer.AddReducer(&r2);
-        reducer.AddReducer(&r3);
-
-        reducer.ReduceGraph();
-
-        Node* end = graph.end();
-        CHECK_EQ(&OPB2, end->op());
-        Node* n1 = end->InputAt(0);
-        Node* n2 = end->InputAt(1);
-        CHECK_NE(n1, n2);
-        CHECK(n1->id() < n2->id());
-        CHECK_EQ(&OPB2, n1->op());
-        CHECK_EQ(&OPB2, n2->op());
-        Node* n4 = n1->InputAt(0);
-        CHECK_EQ(&OPB0, n4->op());
-        CHECK_EQ(n4, n1->InputAt(1));
-        CHECK_EQ(n4, n2->InputAt(0));
-        CHECK_EQ(n4, n2->InputAt(1));
-      }
-    }
-  }
-}
-
-
-TEST(Order) {
-  // Test that the order of reducers doesn't matter, as they should be
-  // rerun for changed nodes.
-  for (int i = 0; i < 2; i++) {
-    GraphTester graph;
-
-    Node* n1 = graph.NewNode(&OPA0);
-    Node* end = graph.NewNode(&OPA1, n1);
-    graph.SetEnd(end);
-
-    GraphReducer reducer(&graph, graph.zone());
-    InPlaceABReducer abr;
-    InPlaceBCReducer bcr;
-    if (i == 0) {
-      reducer.AddReducer(&abr);
-      reducer.AddReducer(&bcr);
-    } else {
-      reducer.AddReducer(&bcr);
-      reducer.AddReducer(&abr);
-    }
-
-    // Tests A* => C* with in-place updates.
-    for (int i = 0; i < 3; i++) {
-      int before = graph.NodeCount();
-      reducer.ReduceGraph();
-      CHECK_EQ(before, graph.NodeCount());
-      CHECK_EQ(&OPC0, n1->op());
-      CHECK_EQ(&OPC1, end->op());
-      CHECK_EQ(n1, end->InputAt(0));
-    }
-  }
-}
diff --git a/test/cctest/compiler/test-graph-visualizer.cc b/test/cctest/compiler/test-graph-visualizer.cc
index ce3e6b7..48be46c 100644
--- a/test/cctest/compiler/test-graph-visualizer.cc
+++ b/test/cctest/compiler/test-graph-visualizer.cc
@@ -2,9 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "src/v8.h"
-#include "test/cctest/cctest.h"
-
 #include "src/compiler/common-operator.h"
 #include "src/compiler/graph.h"
 #include "src/compiler/graph-visualizer.h"
@@ -14,10 +11,19 @@
 #include "src/compiler/operator.h"
 #include "src/compiler/schedule.h"
 #include "src/compiler/scheduler.h"
+#include "src/compiler/source-position.h"
 #include "src/compiler/verifier.h"
+#include "test/cctest/cctest.h"
 
-using namespace v8::internal;
-using namespace v8::internal::compiler;
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+static Operator dummy_operator1(IrOpcode::kParameter, Operator::kNoWrite,
+                                "dummy", 1, 0, 0, 1, 0, 0);
+static Operator dummy_operator6(IrOpcode::kParameter, Operator::kNoWrite,
+                                "dummy", 6, 0, 0, 1, 0, 0);
+
 
 TEST(NodeWithNullInputReachableFromEnd) {
   HandleAndZoneScope scope;
@@ -27,13 +33,14 @@
   Node* start = graph.NewNode(common.Start(0));
   graph.SetStart(start);
   Node* k = graph.NewNode(common.Int32Constant(0));
-  Node* phi = graph.NewNode(common.Phi(kMachAnyTagged, 1), k, start);
+  Node* phi =
+      graph.NewNode(common.Phi(MachineRepresentation::kTagged, 1), k, start);
   phi->ReplaceInput(0, NULL);
   graph.SetEnd(phi);
 
   OFStream os(stdout);
-  os << AsDOT(graph);
-  os << AsJSON(graph);
+  SourcePositionTable table(&graph);
+  os << AsJSON(graph, &table);
 }
 
 
@@ -45,13 +52,14 @@
   Node* start = graph.NewNode(common.Start(0));
   graph.SetStart(start);
   Node* k = graph.NewNode(common.Int32Constant(0));
-  Node* phi = graph.NewNode(common.Phi(kMachAnyTagged, 1), k, start);
+  Node* phi =
+      graph.NewNode(common.Phi(MachineRepresentation::kTagged, 1), k, start);
   phi->ReplaceInput(1, NULL);
   graph.SetEnd(phi);
 
   OFStream os(stdout);
-  os << AsDOT(graph);
-  os << AsJSON(graph);
+  SourcePositionTable table(&graph);
+  os << AsJSON(graph, &table);
 }
 
 
@@ -63,13 +71,14 @@
   Node* start = graph.NewNode(common.Start(0));
   graph.SetStart(start);
   Node* k = graph.NewNode(common.Int32Constant(0));
-  Node* phi = graph.NewNode(common.Phi(kMachAnyTagged, 1), k, start);
+  Node* phi =
+      graph.NewNode(common.Phi(MachineRepresentation::kTagged, 1), k, start);
   phi->ReplaceInput(0, NULL);
   graph.SetEnd(start);
 
   OFStream os(stdout);
-  os << AsDOT(graph);
-  os << AsJSON(graph);
+  SourcePositionTable table(&graph);
+  os << AsJSON(graph, &table);
 }
 
 
@@ -85,6 +94,37 @@
   graph.SetEnd(merge);
 
   OFStream os(stdout);
-  os << AsDOT(graph);
-  os << AsJSON(graph);
+  SourcePositionTable table(&graph);
+  os << AsJSON(graph, &table);
 }
+
+
+TEST(NodeNetworkOfDummiesReachableFromEnd) {
+  HandleAndZoneScope scope;
+  Graph graph(scope.main_zone());
+  CommonOperatorBuilder common(scope.main_zone());
+
+  Node* start = graph.NewNode(common.Start(0));
+  graph.SetStart(start);
+  Node* n2 = graph.NewNode(&dummy_operator1, graph.start());
+  Node* n3 = graph.NewNode(&dummy_operator1, graph.start());
+  Node* n4 = graph.NewNode(&dummy_operator1, n2);
+  Node* n5 = graph.NewNode(&dummy_operator1, n2);
+  Node* n6 = graph.NewNode(&dummy_operator1, n3);
+  Node* n7 = graph.NewNode(&dummy_operator1, n3);
+  Node* n8 = graph.NewNode(&dummy_operator1, n5);
+  Node* n9 = graph.NewNode(&dummy_operator1, n5);
+  Node* n10 = graph.NewNode(&dummy_operator1, n9);
+  Node* n11 = graph.NewNode(&dummy_operator1, n9);
+  Node* end_dependencies[6] = {n4, n8, n10, n11, n6, n7};
+  Node* end = graph.NewNode(&dummy_operator6, 6, end_dependencies);
+  graph.SetEnd(end);
+
+  OFStream os(stdout);
+  SourcePositionTable table(&graph);
+  os << AsJSON(graph, &table);
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/test/cctest/compiler/test-instruction.cc b/test/cctest/compiler/test-instruction.cc
index 294812f..4de3373 100644
--- a/test/cctest/compiler/test-instruction.cc
+++ b/test/cctest/compiler/test-instruction.cc
@@ -2,9 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "src/v8.h"
-#include "test/cctest/cctest.h"
-
 #include "src/compiler/code-generator.h"
 #include "src/compiler/common-operator.h"
 #include "src/compiler/graph.h"
@@ -15,10 +12,11 @@
 #include "src/compiler/operator.h"
 #include "src/compiler/schedule.h"
 #include "src/compiler/scheduler.h"
-#include "src/lithium.h"
+#include "test/cctest/cctest.h"
 
-using namespace v8::internal;
-using namespace v8::internal::compiler;
+namespace v8 {
+namespace internal {
+namespace compiler {
 
 typedef v8::internal::compiler::Instruction TestInstr;
 typedef v8::internal::compiler::InstructionSequence TestInstrSeq;
@@ -27,20 +25,14 @@
 class InstructionTester : public HandleAndZoneScope {
  public:  // We're all friends here.
   InstructionTester()
-      : isolate(main_isolate()),
-        graph(zone()),
+      : graph(zone()),
         schedule(zone()),
-        info(static_cast<HydrogenCodeStub*>(NULL), main_isolate()),
-        linkage(zone(), &info),
         common(zone()),
         machine(zone()),
         code(NULL) {}
 
-  Isolate* isolate;
   Graph graph;
   Schedule schedule;
-  CompilationInfoWithZone info;
-  Linkage linkage;
   CommonOperatorBuilder common;
   MachineOperatorBuilder machine;
   TestInstrSeq* code;
@@ -51,11 +43,12 @@
     if (schedule.rpo_order()->size() == 0) {
       // Compute the RPO order.
       Scheduler::ComputeSpecialRPO(main_zone(), &schedule);
-      DCHECK(schedule.rpo_order()->size() > 0);
+      CHECK_NE(0u, schedule.rpo_order()->size());
     }
     InstructionBlocks* instruction_blocks =
         TestInstrSeq::InstructionBlocksFor(main_zone(), &schedule);
-    code = new (main_zone()) TestInstrSeq(main_zone(), instruction_blocks);
+    code = new (main_zone())
+        TestInstrSeq(main_isolate(), main_zone(), instruction_blocks);
   }
 
   Node* Int32Constant(int32_t val) {
@@ -88,15 +81,16 @@
     return code->AddInstruction(instr);
   }
 
-  UnallocatedOperand* NewUnallocated(int vreg) {
-    UnallocatedOperand* unallocated =
-        new (zone()) UnallocatedOperand(UnallocatedOperand::ANY);
-    unallocated->set_virtual_register(vreg);
-    return unallocated;
+  UnallocatedOperand Unallocated(int vreg) {
+    return UnallocatedOperand(UnallocatedOperand::ANY, vreg);
+  }
+
+  RpoNumber RpoFor(BasicBlock* block) {
+    return RpoNumber::FromInt(block->rpo_number());
   }
 
   InstructionBlock* BlockAt(BasicBlock* block) {
-    return code->InstructionBlockAt(block->GetRpoNumber());
+    return code->InstructionBlockAt(RpoFor(block));
   }
   BasicBlock* GetBasicBlock(int instruction_index) {
     const InstructionBlock* block =
@@ -131,13 +125,9 @@
   BasicBlockVector* blocks = R.schedule.rpo_order();
   CHECK_EQ(static_cast<int>(blocks->size()), R.code->InstructionBlockCount());
 
-  int index = 0;
-  for (BasicBlockVectorIter i = blocks->begin(); i != blocks->end();
-       i++, index++) {
-    BasicBlock* block = *i;
+  for (auto block : *blocks) {
     CHECK_EQ(block->rpo_number(), R.BlockAt(block)->rpo_number().ToInt());
-    CHECK_EQ(block->id().ToInt(), R.BlockAt(block)->id().ToInt());
-    CHECK_EQ(NULL, block->loop_end());
+    CHECK(!block->loop_end());
   }
 }
 
@@ -156,23 +146,23 @@
 
   R.allocCode();
 
-  R.code->StartBlock(b0->GetRpoNumber());
+  R.code->StartBlock(R.RpoFor(b0));
   int i0 = R.NewInstr();
   int i1 = R.NewInstr();
-  R.code->EndBlock(b0->GetRpoNumber());
-  R.code->StartBlock(b1->GetRpoNumber());
+  R.code->EndBlock(R.RpoFor(b0));
+  R.code->StartBlock(R.RpoFor(b1));
   int i2 = R.NewInstr();
   int i3 = R.NewInstr();
   int i4 = R.NewInstr();
   int i5 = R.NewInstr();
-  R.code->EndBlock(b1->GetRpoNumber());
-  R.code->StartBlock(b2->GetRpoNumber());
+  R.code->EndBlock(R.RpoFor(b1));
+  R.code->StartBlock(R.RpoFor(b2));
   int i6 = R.NewInstr();
   int i7 = R.NewInstr();
   int i8 = R.NewInstr();
-  R.code->EndBlock(b2->GetRpoNumber());
-  R.code->StartBlock(b3->GetRpoNumber());
-  R.code->EndBlock(b3->GetRpoNumber());
+  R.code->EndBlock(R.RpoFor(b2));
+  R.code->StartBlock(R.RpoFor(b3));
+  R.code->EndBlock(R.RpoFor(b3));
 
   CHECK_EQ(b0, R.GetBasicBlock(i0));
   CHECK_EQ(b0, R.GetBasicBlock(i1));
@@ -208,20 +198,13 @@
 
   R.allocCode();
   TestInstr* i0 = TestInstr::New(R.zone(), 100);
-  TestInstr* g = TestInstr::New(R.zone(), 103)->MarkAsControl();
-  R.code->StartBlock(b0->GetRpoNumber());
+  TestInstr* g = TestInstr::New(R.zone(), 103);
+  R.code->StartBlock(R.RpoFor(b0));
   R.code->AddInstruction(i0);
   R.code->AddInstruction(g);
-  R.code->EndBlock(b0->GetRpoNumber());
+  R.code->EndBlock(R.RpoFor(b0));
 
-  CHECK_EQ(true, R.code->InstructionAt(0)->IsBlockStart());
-
-  CHECK_EQ(true, R.code->IsGapAt(0));   // Label
-  CHECK_EQ(true, R.code->IsGapAt(1));   // Gap
-  CHECK_EQ(false, R.code->IsGapAt(2));  // i0
-  CHECK_EQ(true, R.code->IsGapAt(3));   // Gap
-  CHECK_EQ(true, R.code->IsGapAt(4));   // Gap
-  CHECK_EQ(false, R.code->IsGapAt(5));  // g
+  CHECK(R.code->instructions().size() == 2);
 }
 
 
@@ -235,36 +218,20 @@
 
   R.allocCode();
   TestInstr* i0 = TestInstr::New(R.zone(), 100);
-  TestInstr* g = TestInstr::New(R.zone(), 103)->MarkAsControl();
-  R.code->StartBlock(b0->GetRpoNumber());
+  TestInstr* g = TestInstr::New(R.zone(), 103);
+  R.code->StartBlock(R.RpoFor(b0));
   R.code->AddInstruction(i0);
   R.code->AddInstruction(g);
-  R.code->EndBlock(b0->GetRpoNumber());
+  R.code->EndBlock(R.RpoFor(b0));
 
   TestInstr* i1 = TestInstr::New(R.zone(), 102);
-  TestInstr* g1 = TestInstr::New(R.zone(), 104)->MarkAsControl();
-  R.code->StartBlock(b1->GetRpoNumber());
+  TestInstr* g1 = TestInstr::New(R.zone(), 104);
+  R.code->StartBlock(R.RpoFor(b1));
   R.code->AddInstruction(i1);
   R.code->AddInstruction(g1);
-  R.code->EndBlock(b1->GetRpoNumber());
+  R.code->EndBlock(R.RpoFor(b1));
 
-  CHECK_EQ(true, R.code->InstructionAt(0)->IsBlockStart());
-
-  CHECK_EQ(true, R.code->IsGapAt(0));   // Label
-  CHECK_EQ(true, R.code->IsGapAt(1));   // Gap
-  CHECK_EQ(false, R.code->IsGapAt(2));  // i0
-  CHECK_EQ(true, R.code->IsGapAt(3));   // Gap
-  CHECK_EQ(true, R.code->IsGapAt(4));   // Gap
-  CHECK_EQ(false, R.code->IsGapAt(5));  // g
-
-  CHECK_EQ(true, R.code->InstructionAt(6)->IsBlockStart());
-
-  CHECK_EQ(true, R.code->IsGapAt(6));    // Label
-  CHECK_EQ(true, R.code->IsGapAt(7));    // Gap
-  CHECK_EQ(false, R.code->IsGapAt(8));   // i1
-  CHECK_EQ(true, R.code->IsGapAt(9));    // Gap
-  CHECK_EQ(true, R.code->IsGapAt(10));   // Gap
-  CHECK_EQ(false, R.code->IsGapAt(11));  // g1
+  CHECK(R.code->instructions().size() == 4);
 }
 
 
@@ -276,43 +243,32 @@
 
   R.allocCode();
   TestInstr* i0 = TestInstr::New(R.zone(), 100);
-  TestInstr* g = TestInstr::New(R.zone(), 103)->MarkAsControl();
-  R.code->StartBlock(b0->GetRpoNumber());
+  TestInstr* g = TestInstr::New(R.zone(), 103);
+  R.code->StartBlock(R.RpoFor(b0));
   R.code->AddInstruction(i0);
   R.code->AddInstruction(g);
-  R.code->EndBlock(b0->GetRpoNumber());
+  R.code->EndBlock(R.RpoFor(b0));
 
-  CHECK_EQ(true, R.code->InstructionAt(0)->IsBlockStart());
+  CHECK(R.code->instructions().size() == 2);
 
-  CHECK_EQ(true, R.code->IsGapAt(0));   // Label
-  CHECK_EQ(true, R.code->IsGapAt(1));   // Gap
-  CHECK_EQ(false, R.code->IsGapAt(2));  // i0
-  CHECK_EQ(true, R.code->IsGapAt(3));   // Gap
-  CHECK_EQ(true, R.code->IsGapAt(4));   // Gap
-  CHECK_EQ(false, R.code->IsGapAt(5));  // g
-
-  int indexes[] = {0, 1, 3, 4, -1};
-  for (int i = 0; indexes[i] >= 0; i++) {
-    int index = indexes[i];
-
-    UnallocatedOperand* op1 = R.NewUnallocated(index + 6);
-    UnallocatedOperand* op2 = R.NewUnallocated(index + 12);
-
-    R.code->AddGapMove(index, op1, op2);
-    GapInstruction* gap = R.code->GapAt(index);
-    ParallelMove* move = gap->GetParallelMove(GapInstruction::START);
-    CHECK_NE(NULL, move);
-    const ZoneList<MoveOperands>* move_operands = move->move_operands();
-    CHECK_EQ(1, move_operands->length());
-    MoveOperands* cur = &move_operands->at(0);
-    CHECK_EQ(op1, cur->source());
-    CHECK_EQ(op2, cur->destination());
+  int index = 0;
+  for (auto instr : R.code->instructions()) {
+    UnallocatedOperand op1 = R.Unallocated(index++);
+    UnallocatedOperand op2 = R.Unallocated(index++);
+    instr->GetOrCreateParallelMove(TestInstr::START, R.zone())
+        ->AddMove(op1, op2);
+    ParallelMove* move = instr->GetParallelMove(TestInstr::START);
+    CHECK(move);
+    CHECK_EQ(1u, move->size());
+    MoveOperands* cur = move->at(0);
+    CHECK(op1.Equals(cur->source()));
+    CHECK(op2.Equals(cur->destination()));
   }
 }
 
 
 TEST(InstructionOperands) {
-  Zone zone(CcTest::InitIsolateOnce());
+  Zone zone;
 
   {
     TestInstr* i = TestInstr::New(&zone, 101);
@@ -321,23 +277,24 @@
     CHECK_EQ(0, static_cast<int>(i->TempCount()));
   }
 
-  InstructionOperand* outputs[] = {
-      new (&zone) UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER),
-      new (&zone) UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER),
-      new (&zone) UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER),
-      new (&zone) UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER)};
+  int vreg = 15;
+  InstructionOperand outputs[] = {
+      UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg),
+      UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg),
+      UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg),
+      UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg)};
 
-  InstructionOperand* inputs[] = {
-      new (&zone) UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER),
-      new (&zone) UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER),
-      new (&zone) UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER),
-      new (&zone) UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER)};
+  InstructionOperand inputs[] = {
+      UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg),
+      UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg),
+      UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg),
+      UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg)};
 
-  InstructionOperand* temps[] = {
-      new (&zone) UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER),
-      new (&zone) UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER),
-      new (&zone) UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER),
-      new (&zone) UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER)};
+  InstructionOperand temps[] = {
+      UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg),
+      UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg),
+      UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg),
+      UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg)};
 
   for (size_t i = 0; i < arraysize(outputs); i++) {
     for (size_t j = 0; j < arraysize(inputs); j++) {
@@ -349,17 +306,21 @@
         CHECK(k == m->TempCount());
 
         for (size_t z = 0; z < i; z++) {
-          CHECK_EQ(outputs[z], m->OutputAt(z));
+          CHECK(outputs[z].Equals(*m->OutputAt(z)));
         }
 
         for (size_t z = 0; z < j; z++) {
-          CHECK_EQ(inputs[z], m->InputAt(z));
+          CHECK(inputs[z].Equals(*m->InputAt(z)));
         }
 
         for (size_t z = 0; z < k; z++) {
-          CHECK_EQ(temps[z], m->TempAt(z));
+          CHECK(temps[z].Equals(*m->TempAt(z)));
         }
       }
     }
   }
 }
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/test/cctest/compiler/test-js-constant-cache.cc b/test/cctest/compiler/test-js-constant-cache.cc
index 8588f66..06169f3 100644
--- a/test/cctest/compiler/test-js-constant-cache.cc
+++ b/test/cctest/compiler/test-js-constant-cache.cc
@@ -2,26 +2,25 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "src/v8.h"
-
 #include "src/assembler.h"
 #include "src/compiler/js-graph.h"
-#include "src/compiler/node-properties-inl.h"
+#include "src/compiler/node-properties.h"
 #include "src/compiler/typer.h"
 #include "src/types.h"
 #include "test/cctest/cctest.h"
 #include "test/cctest/compiler/value-helper.h"
 
-using namespace v8::internal;
-using namespace v8::internal::compiler;
+namespace v8 {
+namespace internal {
+namespace compiler {
 
 class JSCacheTesterHelper {
  protected:
-  explicit JSCacheTesterHelper(Zone* zone)
+  JSCacheTesterHelper(Isolate* isolate, Zone* zone)
       : main_graph_(zone),
         main_common_(zone),
         main_javascript_(zone),
-        main_typer_(&main_graph_, MaybeHandle<Context>()),
+        main_typer_(isolate, &main_graph_),
         main_machine_(zone) {}
   Graph main_graph_;
   CommonOperatorBuilder main_common_;
@@ -37,19 +36,20 @@
                               public JSGraph {
  public:
   JSConstantCacheTester()
-      : JSCacheTesterHelper(main_zone()),
-        JSGraph(&main_graph_, &main_common_, &main_javascript_,
-                &main_machine_) {
+      : JSCacheTesterHelper(main_isolate(), main_zone()),
+        JSGraph(main_isolate(), &main_graph_, &main_common_, &main_javascript_,
+                nullptr, &main_machine_) {
     main_graph_.SetStart(main_graph_.NewNode(common()->Start(0)));
-    main_graph_.SetEnd(main_graph_.NewNode(common()->End()));
+    main_graph_.SetEnd(
+        main_graph_.NewNode(common()->End(1), main_graph_.start()));
     main_typer_.Run();
   }
 
-  Type* upper(Node* node) { return NodeProperties::GetBounds(node).upper; }
+  Type* TypeOf(Node* node) { return NodeProperties::GetType(node); }
 
-  Handle<Object> handle(Node* node) {
+  Handle<HeapObject> handle(Node* node) {
     CHECK_EQ(IrOpcode::kHeapConstant, node->opcode());
-    return OpParameter<Unique<Object> >(node).handle();
+    return OpParameter<Handle<HeapObject>>(node);
   }
 
   Factory* factory() { return main_isolate()->factory(); }
@@ -65,11 +65,11 @@
   CHECK_EQ(zero, T.Constant(0));
   CHECK_NE(zero, T.Constant(-0.0));
   CHECK_NE(zero, T.Constant(1.0));
-  CHECK_NE(zero, T.Constant(v8::base::OS::nan_value()));
+  CHECK_NE(zero, T.Constant(std::numeric_limits<double>::quiet_NaN()));
   CHECK_NE(zero, T.Float64Constant(0));
   CHECK_NE(zero, T.Int32Constant(0));
 
-  Type* t = T.upper(zero);
+  Type* t = T.TypeOf(zero);
 
   CHECK(t->Is(Type::Number()));
   CHECK(t->Is(Type::Integral32()));
@@ -90,7 +90,7 @@
   CHECK_EQ(minus_zero, T.Constant(-0.0));
   CHECK_NE(zero, minus_zero);
 
-  Type* t = T.upper(minus_zero);
+  Type* t = T.TypeOf(minus_zero);
 
   CHECK(t->Is(Type::Number()));
   CHECK(t->Is(Type::MinusZero()));
@@ -103,10 +103,10 @@
   double zero_value = OpParameter<double>(zero);
   double minus_zero_value = OpParameter<double>(minus_zero);
 
-  CHECK_EQ(0.0, zero_value);
-  CHECK_NE(-0.0, zero_value);
-  CHECK_EQ(-0.0, minus_zero_value);
-  CHECK_NE(0.0, minus_zero_value);
+  CHECK(bit_cast<uint64_t>(0.0) == bit_cast<uint64_t>(zero_value));
+  CHECK(bit_cast<uint64_t>(-0.0) != bit_cast<uint64_t>(zero_value));
+  CHECK(bit_cast<uint64_t>(0.0) != bit_cast<uint64_t>(minus_zero_value));
+  CHECK(bit_cast<uint64_t>(-0.0) == bit_cast<uint64_t>(minus_zero_value));
 }
 
 
@@ -119,11 +119,11 @@
   CHECK_EQ(zero, T.ZeroConstant());
   CHECK_NE(zero, T.Constant(-0.0));
   CHECK_NE(zero, T.Constant(1.0));
-  CHECK_NE(zero, T.Constant(v8::base::OS::nan_value()));
+  CHECK_NE(zero, T.Constant(std::numeric_limits<double>::quiet_NaN()));
   CHECK_NE(zero, T.Float64Constant(0));
   CHECK_NE(zero, T.Int32Constant(0));
 
-  Type* t = T.upper(zero);
+  Type* t = T.TypeOf(zero);
 
   CHECK(t->Is(Type::Number()));
   CHECK(t->Is(Type::Integral32()));
@@ -144,11 +144,11 @@
   CHECK_EQ(one, T.Constant(1.0));
   CHECK_NE(one, T.Constant(1.01));
   CHECK_NE(one, T.Constant(-1.01));
-  CHECK_NE(one, T.Constant(v8::base::OS::nan_value()));
+  CHECK_NE(one, T.Constant(std::numeric_limits<double>::quiet_NaN()));
   CHECK_NE(one, T.Float64Constant(1.0));
   CHECK_NE(one, T.Int32Constant(1));
 
-  Type* t = T.upper(one);
+  Type* t = T.TypeOf(one);
 
   CHECK(t->Is(Type::Number()));
   CHECK(t->Is(Type::Integral32()));
@@ -169,11 +169,11 @@
   CHECK_EQ(one, T.Constant(1.0));
   CHECK_NE(one, T.Constant(1.01));
   CHECK_NE(one, T.Constant(-1.01));
-  CHECK_NE(one, T.Constant(v8::base::OS::nan_value()));
+  CHECK_NE(one, T.Constant(std::numeric_limits<double>::quiet_NaN()));
   CHECK_NE(one, T.Float64Constant(1.0));
   CHECK_NE(one, T.Int32Constant(1));
 
-  Type* t = T.upper(one);
+  Type* t = T.TypeOf(one);
 
   CHECK(t->Is(Type::Number()));
   CHECK(t->Is(Type::Integral32()));
@@ -233,7 +233,7 @@
   FOR_FLOAT64_INPUTS(i) {
     double value = *i;
     Node* node = T.Constant(value);
-    CHECK(T.upper(node)->Is(Type::Of(value, T.main_zone())));
+    CHECK(T.TypeOf(node)->Is(Type::Of(value, T.main_zone())));
   }
 }
 
@@ -280,15 +280,15 @@
 TEST(OddballTypes) {
   JSConstantCacheTester T;
 
-  CHECK(T.upper(T.UndefinedConstant())->Is(Type::Undefined()));
+  CHECK(T.TypeOf(T.UndefinedConstant())->Is(Type::Undefined()));
   // TODO(dcarney): figure this out.
-  // CHECK(T.upper(T.TheHoleConstant())->Is(Type::Internal()));
-  CHECK(T.upper(T.TrueConstant())->Is(Type::Boolean()));
-  CHECK(T.upper(T.FalseConstant())->Is(Type::Boolean()));
-  CHECK(T.upper(T.NullConstant())->Is(Type::Null()));
-  CHECK(T.upper(T.ZeroConstant())->Is(Type::Number()));
-  CHECK(T.upper(T.OneConstant())->Is(Type::Number()));
-  CHECK(T.upper(T.NaNConstant())->Is(Type::NaN()));
+  // CHECK(T.TypeOf(T.TheHoleConstant())->Is(Type::Internal()));
+  CHECK(T.TypeOf(T.TrueConstant())->Is(Type::Boolean()));
+  CHECK(T.TypeOf(T.FalseConstant())->Is(Type::Boolean()));
+  CHECK(T.TypeOf(T.NullConstant())->Is(Type::Null()));
+  CHECK(T.TypeOf(T.ZeroConstant())->Is(Type::Number()));
+  CHECK(T.TypeOf(T.OneConstant())->Is(Type::Number()));
+  CHECK(T.TypeOf(T.NaNConstant())->Is(Type::NaN()));
 }
 
 
@@ -335,7 +335,7 @@
                          25, 15, 30,  31,  45,  46,  47,  48};
 
   for (size_t i = 0; i < arraysize(constants); i++) {
-    int count_before = T.graph()->NodeCount();
+    size_t count_before = T.graph()->NodeCount();
     NodeVector nodes_before(T.main_zone());
     T.GetCachedNodes(&nodes_before);
     Node* n = T.Int32Constant(constants[i]);
@@ -357,7 +357,7 @@
                         11,  11,   -33.3, -33.3, -22,  -11};
 
   for (size_t i = 0; i < arraysize(constants); i++) {
-    int count_before = T.graph()->NodeCount();
+    size_t count_before = T.graph()->NodeCount();
     NodeVector nodes_before(T.main_zone());
     T.GetCachedNodes(&nodes_before);
     Node* n = T.Float64Constant(constants[i]);
@@ -379,7 +379,7 @@
                          19,  20,  20, 21, 21, 22, 23,  24,  25};
 
   for (size_t i = 0; i < arraysize(constants); i++) {
-    int count_before = T.graph()->NodeCount();
+    size_t count_before = T.graph()->NodeCount();
     NodeVector nodes_before(T.main_zone());
     T.GetCachedNodes(&nodes_before);
     Node* n = T.Int64Constant(constants[i]);
@@ -401,7 +401,7 @@
                         11,  11,   -33.3, -33.3, -22,  -11};
 
   for (size_t i = 0; i < arraysize(constants); i++) {
-    int count_before = T.graph()->NodeCount();
+    size_t count_before = T.graph()->NodeCount();
     NodeVector nodes_before(T.main_zone());
     T.GetCachedNodes(&nodes_before);
     Node* n = T.Constant(constants[i]);
@@ -428,7 +428,7 @@
                                    ExternalReference::address_of_one_half()};
 
   for (size_t i = 0; i < arraysize(constants); i++) {
-    int count_before = T.graph()->NodeCount();
+    size_t count_before = T.graph()->NodeCount();
     NodeVector nodes_before(T.main_zone());
     T.GetCachedNodes(&nodes_before);
     Node* n = T.ExternalConstant(constants[i]);
@@ -472,3 +472,7 @@
     CHECK(Contains(&nodes, constants[i]));
   }
 }
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/test/cctest/compiler/test-js-context-specialization.cc b/test/cctest/compiler/test-js-context-specialization.cc
index fb7bd94..43b7665 100644
--- a/test/cctest/compiler/test-js-context-specialization.cc
+++ b/test/cctest/compiler/test-js-context-specialization.cc
@@ -3,50 +3,56 @@
 // found in the LICENSE file.
 
 #include "src/compiler/js-context-specialization.h"
+#include "src/compiler/js-graph.h"
 #include "src/compiler/js-operator.h"
 #include "src/compiler/node-matchers.h"
-#include "src/compiler/node-properties-inl.h"
+#include "src/compiler/node-properties.h"
 #include "src/compiler/source-position.h"
 #include "test/cctest/cctest.h"
 #include "test/cctest/compiler/function-tester.h"
 #include "test/cctest/compiler/graph-builder-tester.h"
 
-using namespace v8::internal;
-using namespace v8::internal::compiler;
+namespace v8 {
+namespace internal {
+namespace compiler {
 
-class ContextSpecializationTester : public HandleAndZoneScope,
-                                    public DirectGraphBuilder {
+class ContextSpecializationTester : public HandleAndZoneScope {
  public:
   ContextSpecializationTester()
-      : DirectGraphBuilder(new (main_zone()) Graph(main_zone())),
+      : graph_(new (main_zone()) Graph(main_zone())),
         common_(main_zone()),
         javascript_(main_zone()),
         machine_(main_zone()),
         simplified_(main_zone()),
-        jsgraph_(graph(), common(), &javascript_, &machine_),
-        info_(main_isolate(), main_zone()) {}
+        jsgraph_(main_isolate(), graph(), common(), &javascript_, &simplified_,
+                 &machine_),
+        reducer_(main_zone(), graph()),
+        spec_(&reducer_, jsgraph(), MaybeHandle<Context>()) {}
 
+  JSContextSpecialization* spec() { return &spec_; }
   Factory* factory() { return main_isolate()->factory(); }
   CommonOperatorBuilder* common() { return &common_; }
   JSOperatorBuilder* javascript() { return &javascript_; }
   SimplifiedOperatorBuilder* simplified() { return &simplified_; }
   JSGraph* jsgraph() { return &jsgraph_; }
-  CompilationInfo* info() { return &info_; }
+  Graph* graph() { return graph_; }
 
  private:
+  Graph* graph_;
   CommonOperatorBuilder common_;
   JSOperatorBuilder javascript_;
   MachineOperatorBuilder machine_;
   SimplifiedOperatorBuilder simplified_;
   JSGraph jsgraph_;
-  CompilationInfo info_;
+  GraphReducer reducer_;
+  JSContextSpecialization spec_;
 };
 
 
 TEST(ReduceJSLoadContext) {
   ContextSpecializationTester t;
 
-  Node* start = t.NewNode(t.common()->Start(0));
+  Node* start = t.graph()->NewNode(t.common()->Start(0));
   t.graph()->SetStart(start);
 
   // Make a context and initialize it a bit for this test.
@@ -56,41 +62,40 @@
   subcontext2->set_previous(*subcontext1);
   subcontext1->set_previous(*native);
   Handle<Object> expected = t.factory()->InternalizeUtf8String("gboy!");
-  const int slot = Context::GLOBAL_OBJECT_INDEX;
+  const int slot = Context::NATIVE_CONTEXT_INDEX;
   native->set(slot, *expected);
 
   Node* const_context = t.jsgraph()->Constant(native);
   Node* deep_const_context = t.jsgraph()->Constant(subcontext2);
-  Node* param_context = t.NewNode(t.common()->Parameter(0), start);
-  JSContextSpecializer spec(t.info(), t.jsgraph(), const_context);
+  Node* param_context = t.graph()->NewNode(t.common()->Parameter(0), start);
 
   {
     // Mutable slot, constant context, depth = 0 => do nothing.
-    Node* load = t.NewNode(t.javascript()->LoadContext(0, 0, false),
-                           const_context, const_context, start);
-    Reduction r = spec.ReduceJSLoadContext(load);
+    Node* load = t.graph()->NewNode(t.javascript()->LoadContext(0, 0, false),
+                                    const_context, const_context, start);
+    Reduction r = t.spec()->Reduce(load);
     CHECK(!r.Changed());
   }
 
   {
     // Mutable slot, non-constant context, depth = 0 => do nothing.
-    Node* load = t.NewNode(t.javascript()->LoadContext(0, 0, false),
-                           param_context, param_context, start);
-    Reduction r = spec.ReduceJSLoadContext(load);
+    Node* load = t.graph()->NewNode(t.javascript()->LoadContext(0, 0, false),
+                                    param_context, param_context, start);
+    Reduction r = t.spec()->Reduce(load);
     CHECK(!r.Changed());
   }
 
   {
     // Mutable slot, constant context, depth > 0 => fold-in parent context.
-    Node* load = t.NewNode(
+    Node* load = t.graph()->NewNode(
         t.javascript()->LoadContext(2, Context::GLOBAL_EVAL_FUN_INDEX, false),
         deep_const_context, deep_const_context, start);
-    Reduction r = spec.ReduceJSLoadContext(load);
+    Reduction r = t.spec()->Reduce(load);
     CHECK(r.Changed());
     Node* new_context_input = NodeProperties::GetValueInput(r.replacement(), 0);
     CHECK_EQ(IrOpcode::kHeapConstant, new_context_input->opcode());
-    HeapObjectMatcher<Context> match(new_context_input);
-    CHECK_EQ(*native, *match.Value().handle());
+    HeapObjectMatcher match(new_context_input);
+    CHECK_EQ(*native, *match.Value());
     ContextAccess access = OpParameter<ContextAccess>(r.replacement());
     CHECK_EQ(Context::GLOBAL_EVAL_FUN_INDEX, static_cast<int>(access.index()));
     CHECK_EQ(0, static_cast<int>(access.depth()));
@@ -99,15 +104,15 @@
 
   {
     // Immutable slot, constant context, depth = 0 => specialize.
-    Node* load = t.NewNode(t.javascript()->LoadContext(0, slot, true),
-                           const_context, const_context, start);
-    Reduction r = spec.ReduceJSLoadContext(load);
+    Node* load = t.graph()->NewNode(t.javascript()->LoadContext(0, slot, true),
+                                    const_context, const_context, start);
+    Reduction r = t.spec()->Reduce(load);
     CHECK(r.Changed());
     CHECK(r.replacement() != load);
 
-    HeapObjectMatcher<Object> match(r.replacement());
+    HeapObjectMatcher match(r.replacement());
     CHECK(match.HasValue());
-    CHECK_EQ(*expected, *match.Value().handle());
+    CHECK_EQ(*expected, *match.Value());
   }
 
   // TODO(titzer): test with other kinds of contexts, e.g. a function context.
@@ -118,7 +123,7 @@
 TEST(ReduceJSStoreContext) {
   ContextSpecializationTester t;
 
-  Node* start = t.NewNode(t.common()->Start(0));
+  Node* start = t.graph()->NewNode(t.common()->Start(0));
   t.graph()->SetStart(start);
 
   // Make a context and initialize it a bit for this test.
@@ -128,49 +133,51 @@
   subcontext2->set_previous(*subcontext1);
   subcontext1->set_previous(*native);
   Handle<Object> expected = t.factory()->InternalizeUtf8String("gboy!");
-  const int slot = Context::GLOBAL_OBJECT_INDEX;
+  const int slot = Context::NATIVE_CONTEXT_INDEX;
   native->set(slot, *expected);
 
   Node* const_context = t.jsgraph()->Constant(native);
   Node* deep_const_context = t.jsgraph()->Constant(subcontext2);
-  Node* param_context = t.NewNode(t.common()->Parameter(0), start);
-  JSContextSpecializer spec(t.info(), t.jsgraph(), const_context);
+  Node* param_context = t.graph()->NewNode(t.common()->Parameter(0), start);
 
   {
     // Mutable slot, constant context, depth = 0 => do nothing.
-    Node* load = t.NewNode(t.javascript()->StoreContext(0, 0), const_context,
-                           const_context, start);
-    Reduction r = spec.ReduceJSStoreContext(load);
+    Node* load =
+        t.graph()->NewNode(t.javascript()->StoreContext(0, 0), const_context,
+                           const_context, const_context, start, start);
+    Reduction r = t.spec()->Reduce(load);
     CHECK(!r.Changed());
   }
 
   {
     // Mutable slot, non-constant context, depth = 0 => do nothing.
-    Node* load = t.NewNode(t.javascript()->StoreContext(0, 0), param_context,
-                           param_context, start);
-    Reduction r = spec.ReduceJSStoreContext(load);
+    Node* load =
+        t.graph()->NewNode(t.javascript()->StoreContext(0, 0), param_context,
+                           param_context, const_context, start, start);
+    Reduction r = t.spec()->Reduce(load);
     CHECK(!r.Changed());
   }
 
   {
     // Immutable slot, constant context, depth = 0 => do nothing.
-    Node* load = t.NewNode(t.javascript()->StoreContext(0, slot), const_context,
-                           const_context, start);
-    Reduction r = spec.ReduceJSStoreContext(load);
+    Node* load =
+        t.graph()->NewNode(t.javascript()->StoreContext(0, slot), const_context,
+                           const_context, const_context, start, start);
+    Reduction r = t.spec()->Reduce(load);
     CHECK(!r.Changed());
   }
 
   {
     // Mutable slot, constant context, depth > 0 => fold-in parent context.
-    Node* load = t.NewNode(
+    Node* load = t.graph()->NewNode(
         t.javascript()->StoreContext(2, Context::GLOBAL_EVAL_FUN_INDEX),
-        deep_const_context, deep_const_context, start);
-    Reduction r = spec.ReduceJSStoreContext(load);
+        deep_const_context, deep_const_context, const_context, start, start);
+    Reduction r = t.spec()->Reduce(load);
     CHECK(r.Changed());
     Node* new_context_input = NodeProperties::GetValueInput(r.replacement(), 0);
     CHECK_EQ(IrOpcode::kHeapConstant, new_context_input->opcode());
-    HeapObjectMatcher<Context> match(new_context_input);
-    CHECK_EQ(*native, *match.Value().handle());
+    HeapObjectMatcher match(new_context_input);
+    CHECK_EQ(*native, *match.Value());
     ContextAccess access = OpParameter<ContextAccess>(r.replacement());
     CHECK_EQ(Context::GLOBAL_EVAL_FUN_INDEX, static_cast<int>(access.index()));
     CHECK_EQ(0, static_cast<int>(access.depth()));
@@ -188,40 +195,43 @@
 TEST(SpecializeToContext) {
   ContextSpecializationTester t;
 
-  Node* start = t.NewNode(t.common()->Start(0));
+  Node* start = t.graph()->NewNode(t.common()->Start(0));
   t.graph()->SetStart(start);
 
   // Make a context and initialize it a bit for this test.
   Handle<Context> native = t.factory()->NewNativeContext();
   Handle<Object> expected = t.factory()->InternalizeUtf8String("gboy!");
-  const int slot = Context::GLOBAL_OBJECT_INDEX;
+  const int slot = Context::NATIVE_CONTEXT_INDEX;
   native->set(slot, *expected);
-  t.info()->SetContext(native);
 
   Node* const_context = t.jsgraph()->Constant(native);
-  Node* param_context = t.NewNode(t.common()->Parameter(0), start);
-  JSContextSpecializer spec(t.info(), t.jsgraph(), const_context);
+  Node* param_context = t.graph()->NewNode(t.common()->Parameter(0), start);
 
   {
     // Check that specialization replaces values and forwards effects
     // correctly, and folds values from constant and non-constant contexts
     Node* effect_in = start;
-    Node* load = t.NewNode(t.javascript()->LoadContext(0, slot, true),
-                           const_context, const_context, effect_in);
+    Node* load = t.graph()->NewNode(t.javascript()->LoadContext(0, slot, true),
+                                    const_context, const_context, effect_in);
 
 
-    Node* value_use = t.NewNode(t.simplified()->ChangeTaggedToInt32(), load);
-    Node* other_load = t.NewNode(t.javascript()->LoadContext(0, slot, true),
-                                 param_context, param_context, load);
+    Node* value_use =
+        t.graph()->NewNode(t.simplified()->ChangeTaggedToInt32(), load);
+    Node* other_load =
+        t.graph()->NewNode(t.javascript()->LoadContext(0, slot, true),
+                           param_context, param_context, load);
     Node* effect_use = other_load;
     Node* other_use =
-        t.NewNode(t.simplified()->ChangeTaggedToInt32(), other_load);
+        t.graph()->NewNode(t.simplified()->ChangeTaggedToInt32(), other_load);
 
-    Node* add = t.NewNode(t.javascript()->Add(), value_use, other_use,
-                          param_context, other_load, start);
+    Node* add = t.graph()->NewNode(
+        t.javascript()->Add(LanguageMode::SLOPPY, BinaryOperationHints::Any()),
+        value_use, other_use, param_context, t.jsgraph()->EmptyFrameState(),
+        t.jsgraph()->EmptyFrameState(), other_load, start);
 
-    Node* ret = t.NewNode(t.common()->Return(), add, effect_use, start);
-    Node* end = t.NewNode(t.common()->End(), ret);
+    Node* ret =
+        t.graph()->NewNode(t.common()->Return(), add, effect_use, start);
+    Node* end = t.graph()->NewNode(t.common()->End(1), ret);
     USE(end);
     t.graph()->SetEnd(end);
 
@@ -230,7 +240,9 @@
     CheckEffectInput(load, effect_use);
 
     // Perform the reduction on the entire graph.
-    GraphReducer graph_reducer(t.graph(), t.main_zone());
+    GraphReducer graph_reducer(t.main_zone(), t.graph());
+    JSContextSpecialization spec(&graph_reducer, t.jsgraph(),
+                                 MaybeHandle<Context>());
     graph_reducer.AddReducer(&spec);
     graph_reducer.ReduceGraph();
 
@@ -241,9 +253,9 @@
     CHECK_EQ(other_load, other_use->InputAt(0));
 
     Node* replacement = value_use->InputAt(0);
-    HeapObjectMatcher<Object> match(replacement);
+    HeapObjectMatcher match(replacement);
     CHECK(match.HasValue());
-    CHECK_EQ(*expected, *match.Value().handle());
+    CHECK_EQ(*expected, *match.Value());
   }
   // TODO(titzer): clean up above test and test more complicated effects.
 }
@@ -304,3 +316,7 @@
     CHECK(T.Call(T.Val(-2.1), T.Val(0.0)).ToHandleChecked()->IsNaN());
   }
 }
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/test/cctest/compiler/test-js-typed-lowering.cc b/test/cctest/compiler/test-js-typed-lowering.cc
index 3023837..c8b7734 100644
--- a/test/cctest/compiler/test-js-typed-lowering.cc
+++ b/test/cctest/compiler/test-js-typed-lowering.cc
@@ -2,17 +2,33 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "src/compiler/graph-inl.h"
+#include "src/compilation-dependencies.h"
 #include "src/compiler/js-graph.h"
 #include "src/compiler/js-typed-lowering.h"
 #include "src/compiler/machine-operator.h"
-#include "src/compiler/node-properties-inl.h"
+#include "src/compiler/node-properties.h"
 #include "src/compiler/opcodes.h"
+#include "src/compiler/operator-properties.h"
+#include "src/compiler/simplified-operator.h"
 #include "src/compiler/typer.h"
 #include "test/cctest/cctest.h"
 
-using namespace v8::internal;
-using namespace v8::internal::compiler;
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+#ifndef TEST_WITH_STRONG
+#define TEST_WITH_STRONG(Name)                                                 \
+  static void Test##Name();                                                    \
+  static void TestWithStrong##Name(LanguageMode language_mode);                \
+  CcTest register_test_##Name(Test##Name, __FILE__, #Name, NULL, true, true);  \
+  static void Test##Name() {                                                   \
+    TestWithStrong##Name(LanguageMode::SLOPPY);                                \
+    TestWithStrong##Name(LanguageMode::STRONG);                                \
+  }                                                                            \
+  static void TestWithStrong##Name(LanguageMode language_mode)
+#endif
+
 
 class JSTypedLoweringTester : public HandleAndZoneScope {
  public:
@@ -24,11 +40,12 @@
         machine(main_zone()),
         simplified(main_zone()),
         common(main_zone()),
+        deps(main_isolate(), main_zone()),
         graph(main_zone()),
-        typer(&graph, MaybeHandle<Context>()),
+        typer(main_isolate(), &graph),
         context_node(NULL) {
     graph.SetStart(graph.NewNode(common.Start(num_parameters)));
-    graph.SetEnd(graph.NewNode(common.End()));
+    graph.SetEnd(graph.NewNode(common.End(1), graph.start()));
     typer.Run();
   }
 
@@ -39,26 +56,25 @@
   MachineOperatorBuilder machine;
   SimplifiedOperatorBuilder simplified;
   CommonOperatorBuilder common;
+  CompilationDependencies deps;
   Graph graph;
   Typer typer;
   Node* context_node;
+  BinaryOperationHints const hints = BinaryOperationHints::Any();
 
   Node* Parameter(Type* t, int32_t index = 0) {
     Node* n = graph.NewNode(common.Parameter(index), graph.start());
-    NodeProperties::SetBounds(n, Bounds(Type::None(), t));
+    NodeProperties::SetType(n, t);
     return n;
   }
 
   Node* UndefinedConstant() {
-    Unique<HeapObject> unique = Unique<HeapObject>::CreateImmovable(
-        isolate->factory()->undefined_value());
-    return graph.NewNode(common.HeapConstant(unique));
+    Handle<HeapObject> value = isolate->factory()->undefined_value();
+    return graph.NewNode(common.HeapConstant(value));
   }
 
   Node* HeapConstant(Handle<HeapObject> constant) {
-    Unique<HeapObject> unique =
-        Unique<HeapObject>::CreateUninitialized(constant);
-    return graph.NewNode(common.HeapConstant(unique));
+    return graph.NewNode(common.HeapConstant(constant));
   }
 
   Node* EmptyFrameState(Node* context) {
@@ -66,17 +82,22 @@
     Node* locals = graph.NewNode(common.StateValues(0));
     Node* stack = graph.NewNode(common.StateValues(0));
 
-    Node* state_node =
-        graph.NewNode(common.FrameState(JS_FRAME, BailoutId(0),
-                                        OutputFrameStateCombine::Ignore()),
-                      parameters, locals, stack, context, UndefinedConstant());
+    Node* state_node = graph.NewNode(
+        common.FrameState(BailoutId::None(), OutputFrameStateCombine::Ignore(),
+                          nullptr),
+        parameters, locals, stack, context, UndefinedConstant(), graph.start());
 
     return state_node;
   }
 
   Node* reduce(Node* node) {
-    JSGraph jsgraph(&graph, &common, &javascript, &machine);
-    JSTypedLowering reducer(&jsgraph, main_zone());
+    JSGraph jsgraph(main_isolate(), &graph, &common, &javascript, &simplified,
+                    &machine);
+    // TODO(titzer): mock the GraphReducer here for better unit testing.
+    GraphReducer graph_reducer(main_zone(), &graph);
+    JSTypedLowering reducer(&graph_reducer, &deps,
+                            JSTypedLowering::kDeoptimizationEnabled, &jsgraph,
+                            main_zone());
     Reduction reduction = reducer.Reduce(node);
     if (reduction.Changed()) return reduction.replacement();
     return node;
@@ -93,14 +114,12 @@
 
   Node* control() { return start(); }
 
-  void CheckPureBinop(IrOpcode::Value expected, Node* node) {
+  void CheckBinop(IrOpcode::Value expected, Node* node) {
     CHECK_EQ(expected, node->opcode());
-    CHECK_EQ(2, node->InputCount());  // should not have context, effect, etc.
   }
 
-  void CheckPureBinop(const Operator* expected, Node* node) {
+  void CheckBinop(const Operator* expected, Node* node) {
     CHECK_EQ(expected->opcode(), node->op()->opcode());
-    CHECK_EQ(2, node->InputCount());  // should not have context, effect, etc.
   }
 
   Node* ReduceUnop(const Operator* op, Type* input_type) {
@@ -113,18 +132,48 @@
 
   Node* Binop(const Operator* op, Node* left, Node* right) {
     // JS binops also require context, effect, and control
-    return graph.NewNode(op, left, right, context(), start(), control());
+    std::vector<Node*> inputs;
+    inputs.push_back(left);
+    inputs.push_back(right);
+    if (OperatorProperties::HasContextInput(op)) {
+      inputs.push_back(context());
+    }
+    for (int i = 0; i < OperatorProperties::GetFrameStateInputCount(op); i++) {
+      inputs.push_back(EmptyFrameState(context()));
+    }
+    if (op->EffectInputCount() > 0) {
+      inputs.push_back(start());
+    }
+    if (op->ControlInputCount() > 0) {
+      inputs.push_back(control());
+    }
+    return graph.NewNode(op, static_cast<int>(inputs.size()),
+                         &(inputs.front()));
   }
 
   Node* Unop(const Operator* op, Node* input) {
     // JS unops also require context, effect, and control
-    return graph.NewNode(op, input, context(), start(), control());
+    if (OperatorProperties::GetFrameStateInputCount(op) > 0) {
+      CHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(op));
+      return graph.NewNode(op, input, context(), EmptyFrameState(context()),
+                           start(), control());
+    } else {
+      return graph.NewNode(op, input, context(), start(), control());
+    }
   }
 
   Node* UseForEffect(Node* node) {
     // TODO(titzer): use EffectPhi after fixing EffectCount
-    return graph.NewNode(javascript.ToNumber(), node, context(), node,
-                         control());
+    if (OperatorProperties::GetFrameStateInputCount(javascript.ToNumber()) >
+        0) {
+      CHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(
+                      javascript.ToNumber()));
+      return graph.NewNode(javascript.ToNumber(), node, context(),
+                           EmptyFrameState(context()), node, control());
+    } else {
+      return graph.NewNode(javascript.ToNumber(), node, context(), node,
+                           control());
+    }
   }
 
   void CheckEffectInput(Node* effect, Node* use) {
@@ -155,9 +204,9 @@
     CheckHandle(isolate->factory()->false_value(), result);
   }
 
-  void CheckHandle(Handle<Object> expected, Node* result) {
+  void CheckHandle(Handle<HeapObject> expected, Node* result) {
     CHECK_EQ(IrOpcode::kHeapConstant, result->opcode());
-    Handle<Object> value = OpParameter<Unique<Object> >(result).handle();
+    Handle<HeapObject> value = OpParameter<Handle<HeapObject>>(result);
     CHECK_EQ(*expected, *value);
   }
 };
@@ -166,24 +215,17 @@
                                Type::String()};
 
 
-static Type* kInt32Types[] = {
-    Type::UnsignedSmall(),       Type::NegativeSigned32(),
-    Type::NonNegativeSigned32(), Type::SignedSmall(),
-    Type::Signed32(),            Type::Unsigned32(),
-    Type::Integral32()};
+static Type* kInt32Types[] = {Type::UnsignedSmall(), Type::Negative32(),
+                              Type::Unsigned31(),    Type::SignedSmall(),
+                              Type::Signed32(),      Type::Unsigned32(),
+                              Type::Integral32()};
 
 
 static Type* kNumberTypes[] = {
-    Type::UnsignedSmall(),       Type::NegativeSigned32(),
-    Type::NonNegativeSigned32(), Type::SignedSmall(),
-    Type::Signed32(),            Type::Unsigned32(),
-    Type::Integral32(),          Type::MinusZero(),
-    Type::NaN(),                 Type::OrderedNumber(),
-    Type::PlainNumber(),         Type::Number()};
-
-
-static Type* kJSTypes[] = {Type::Undefined(), Type::Null(),   Type::Boolean(),
-                           Type::Number(),    Type::String(), Type::Object()};
+    Type::UnsignedSmall(), Type::Negative32(),  Type::Unsigned31(),
+    Type::SignedSmall(),   Type::Signed32(),    Type::Unsigned32(),
+    Type::Integral32(),    Type::MinusZero(),   Type::NaN(),
+    Type::OrderedNumber(), Type::PlainNumber(), Type::Number()};
 
 
 static Type* I32Type(bool is_signed) {
@@ -198,7 +240,7 @@
 
 // TODO(turbofan): Lowering of StringAdd is disabled for now.
 #if 0
-TEST(StringBinops) {
+TEST_WITH_STRONG(StringBinops) {
   JSTypedLoweringTester R;
 
   for (size_t i = 0; i < arraysize(kStringTypes); ++i) {
@@ -207,10 +249,10 @@
     for (size_t j = 0; j < arraysize(kStringTypes); ++j) {
       Node* p1 = R.Parameter(kStringTypes[j], 1);
 
-      Node* add = R.Binop(R.javascript.Add(), p0, p1);
+      Node* add = R.Binop(R.javascript.Add(language_mode), p0, p1);
       Node* r = R.reduce(add);
 
-      R.CheckPureBinop(IrOpcode::kStringAdd, r);
+      R.CheckBinop(IrOpcode::kStringAdd, r);
       CHECK_EQ(p0, r->InputAt(0));
       CHECK_EQ(p1, r->InputAt(1));
     }
@@ -219,29 +261,35 @@
 #endif
 
 
-TEST(AddNumber1) {
+TEST_WITH_STRONG(AddNumber1) {
   JSTypedLoweringTester R;
   for (size_t i = 0; i < arraysize(kNumberTypes); ++i) {
     Node* p0 = R.Parameter(kNumberTypes[i], 0);
     Node* p1 = R.Parameter(kNumberTypes[i], 1);
-    Node* add = R.Binop(R.javascript.Add(), p0, p1);
+    Node* add = R.Binop(
+        R.javascript.Add(language_mode, BinaryOperationHints::Any()), p0, p1);
     Node* r = R.reduce(add);
 
-    R.CheckPureBinop(IrOpcode::kNumberAdd, r);
+    R.CheckBinop(IrOpcode::kNumberAdd, r);
     CHECK_EQ(p0, r->InputAt(0));
     CHECK_EQ(p1, r->InputAt(1));
   }
 }
 
 
-TEST(NumberBinops) {
+TEST_WITH_STRONG(NumberBinops) {
   JSTypedLoweringTester R;
   const Operator* ops[] = {
-      R.javascript.Add(),      R.simplified.NumberAdd(),
-      R.javascript.Subtract(), R.simplified.NumberSubtract(),
-      R.javascript.Multiply(), R.simplified.NumberMultiply(),
-      R.javascript.Divide(),   R.simplified.NumberDivide(),
-      R.javascript.Modulus(),  R.simplified.NumberModulus(),
+      R.javascript.Add(language_mode, R.hints),
+      R.simplified.NumberAdd(),
+      R.javascript.Subtract(language_mode, R.hints),
+      R.simplified.NumberSubtract(),
+      R.javascript.Multiply(language_mode, R.hints),
+      R.simplified.NumberMultiply(),
+      R.javascript.Divide(language_mode, R.hints),
+      R.simplified.NumberDivide(),
+      R.javascript.Modulus(language_mode, R.hints),
+      R.simplified.NumberModulus(),
   };
 
   for (size_t i = 0; i < arraysize(kNumberTypes); ++i) {
@@ -254,7 +302,7 @@
         Node* add = R.Binop(ops[k], p0, p1);
         Node* r = R.reduce(add);
 
-        R.CheckPureBinop(ops[k + 1], r);
+        R.CheckBinop(ops[k + 1], r);
         CHECK_EQ(p0, r->InputAt(0));
         CHECK_EQ(p1, r->InputAt(1));
       }
@@ -264,8 +312,8 @@
 
 
 static void CheckToI32(Node* old_input, Node* new_input, bool is_signed) {
-  Type* old_type = NodeProperties::GetBounds(old_input).upper;
-  Type* new_type = NodeProperties::GetBounds(new_input).upper;
+  Type* old_type = NodeProperties::GetType(old_input);
+  Type* new_type = NodeProperties::GetType(new_input);
   Type* expected_type = I32Type(is_signed);
   CHECK(new_type->Is(expected_type));
   if (old_type->Is(expected_type)) {
@@ -281,21 +329,22 @@
 // A helper class for testing lowering of bitwise shift operators.
 class JSBitwiseShiftTypedLoweringTester : public JSTypedLoweringTester {
  public:
+  explicit JSBitwiseShiftTypedLoweringTester(LanguageMode language_mode)
+      : JSTypedLoweringTester(), language_mode_(language_mode) {
+    int i = 0;
+    set(i++, javascript.ShiftLeft(language_mode_, hints), true);
+    set(i++, simplified.NumberShiftLeft(), false);
+    set(i++, javascript.ShiftRight(language_mode_, hints), true);
+    set(i++, simplified.NumberShiftRight(), false);
+    set(i++, javascript.ShiftRightLogical(language_mode_, hints), false);
+    set(i++, simplified.NumberShiftRightLogical(), false);
+  }
   static const int kNumberOps = 6;
   const Operator* ops[kNumberOps];
   bool signedness[kNumberOps];
 
-  JSBitwiseShiftTypedLoweringTester() {
-    int i = 0;
-    set(i++, javascript.ShiftLeft(), true);
-    set(i++, machine.Word32Shl(), false);
-    set(i++, javascript.ShiftRight(), true);
-    set(i++, machine.Word32Sar(), false);
-    set(i++, javascript.ShiftRightLogical(), false);
-    set(i++, machine.Word32Shr(), false);
-  }
-
  private:
+  LanguageMode language_mode_;
   void set(int idx, const Operator* op, bool s) {
     ops[idx] = op;
     signedness[idx] = s;
@@ -304,15 +353,14 @@
 
 
 TEST(Int32BitwiseShifts) {
-  JSBitwiseShiftTypedLoweringTester R;
+  JSBitwiseShiftTypedLoweringTester R(LanguageMode::SLOPPY);
 
-  Type* types[] = {Type::SignedSmall(),      Type::UnsignedSmall(),
-                   Type::NegativeSigned32(), Type::NonNegativeSigned32(),
-                   Type::Unsigned32(),       Type::Signed32(),
-                   Type::MinusZero(),        Type::NaN(),
-                   Type::Undefined(),        Type::Null(),
-                   Type::Boolean(),          Type::Number(),
-                   Type::PlainNumber(),      Type::String()};
+  Type* types[] = {
+      Type::SignedSmall(), Type::UnsignedSmall(), Type::Negative32(),
+      Type::Unsigned31(),  Type::Unsigned32(),    Type::Signed32(),
+      Type::MinusZero(),   Type::NaN(),           Type::Undefined(),
+      Type::Null(),        Type::Boolean(),       Type::Number(),
+      Type::PlainNumber(), Type::String()};
 
   for (size_t i = 0; i < arraysize(types); ++i) {
     Node* p0 = R.Parameter(types[i], 0);
@@ -324,19 +372,12 @@
         Node* add = R.Binop(R.ops[k], p0, p1);
         Node* r = R.reduce(add);
 
-        R.CheckPureBinop(R.ops[k + 1], r);
+        R.CheckBinop(R.ops[k + 1], r);
         Node* r0 = r->InputAt(0);
         Node* r1 = r->InputAt(1);
 
         CheckToI32(p0, r0, R.signedness[k]);
-
-        if (r1->opcode() == IrOpcode::kWord32And) {
-          R.CheckPureBinop(IrOpcode::kWord32And, r1);
-          CheckToI32(p1, r1->InputAt(0), R.signedness[k + 1]);
-          R.CheckInt32Constant(0x1F, r1->InputAt(1));
-        } else {
-          CheckToI32(p1, r1, R.signedness[k]);
-        }
+        CheckToI32(p1, r1, false);
       }
     }
   }
@@ -346,21 +387,22 @@
 // A helper class for testing lowering of bitwise operators.
 class JSBitwiseTypedLoweringTester : public JSTypedLoweringTester {
  public:
+  explicit JSBitwiseTypedLoweringTester(LanguageMode language_mode)
+      : JSTypedLoweringTester(), language_mode_(language_mode) {
+    int i = 0;
+    set(i++, javascript.BitwiseOr(language_mode_, hints), true);
+    set(i++, simplified.NumberBitwiseOr(), true);
+    set(i++, javascript.BitwiseXor(language_mode_, hints), true);
+    set(i++, simplified.NumberBitwiseXor(), true);
+    set(i++, javascript.BitwiseAnd(language_mode_, hints), true);
+    set(i++, simplified.NumberBitwiseAnd(), true);
+  }
   static const int kNumberOps = 6;
   const Operator* ops[kNumberOps];
   bool signedness[kNumberOps];
 
-  JSBitwiseTypedLoweringTester() {
-    int i = 0;
-    set(i++, javascript.BitwiseOr(), true);
-    set(i++, machine.Word32Or(), true);
-    set(i++, javascript.BitwiseXor(), true);
-    set(i++, machine.Word32Xor(), true);
-    set(i++, javascript.BitwiseAnd(), true);
-    set(i++, machine.Word32And(), true);
-  }
-
  private:
+  LanguageMode language_mode_;
   void set(int idx, const Operator* op, bool s) {
     ops[idx] = op;
     signedness[idx] = s;
@@ -369,7 +411,7 @@
 
 
 TEST(Int32BitwiseBinops) {
-  JSBitwiseTypedLoweringTester R;
+  JSBitwiseTypedLoweringTester R(LanguageMode::SLOPPY);
 
   Type* types[] = {
       Type::SignedSmall(),   Type::UnsignedSmall(), Type::Unsigned32(),
@@ -388,7 +430,7 @@
         Node* add = R.Binop(R.ops[k], p0, p1);
         Node* r = R.reduce(add);
 
-        R.CheckPureBinop(R.ops[k + 1], r);
+        R.CheckBinop(R.ops[k + 1], r);
 
         CheckToI32(p0, r->InputAt(0), R.signedness[k]);
         CheckToI32(p1, r->InputAt(1), R.signedness[k + 1]);
@@ -426,8 +468,9 @@
 
   for (size_t i = 0; i < arraysize(types); i++) {
     Node* n = R.Parameter(types[i]);
-    Node* c = R.graph.NewNode(R.javascript.ToNumber(), n, R.context(),
-                              R.start(), R.start());
+    Node* c =
+        R.graph.NewNode(R.javascript.ToNumber(), n, R.context(),
+                        R.EmptyFrameState(R.context()), R.start(), R.start());
     Node* effect_use = R.UseForEffect(c);
     Node* add = R.graph.NewNode(R.simplified.ReferenceEqual(Type::Any()), n, c);
 
@@ -462,7 +505,7 @@
     // Note that either outcome below is correct. It only depends on whether
     // the types of constants are eagerly computed or only computed by the
     // typing pass.
-    if (NodeProperties::GetBounds(n).upper->Is(Type::Number())) {
+    if (NodeProperties::GetType(n)->Is(Type::Number())) {
       // If number constants are eagerly typed, then reduction should
       // remove the ToNumber.
       CHECK_EQ(n, r);
@@ -488,42 +531,6 @@
 }
 
 
-TEST(JSToBoolean) {
-  JSTypedLoweringTester R;
-  const Operator* op = R.javascript.ToBoolean();
-
-  {  // ToBoolean(undefined)
-    Node* r = R.ReduceUnop(op, Type::Undefined());
-    R.CheckFalse(r);
-  }
-
-  {  // ToBoolean(null)
-    Node* r = R.ReduceUnop(op, Type::Null());
-    R.CheckFalse(r);
-  }
-
-  {  // ToBoolean(boolean)
-    Node* r = R.ReduceUnop(op, Type::Boolean());
-    CHECK_EQ(IrOpcode::kParameter, r->opcode());
-  }
-
-  {  // ToBoolean(object)
-    Node* r = R.ReduceUnop(op, Type::DetectableObject());
-    R.CheckTrue(r);
-  }
-
-  {  // ToBoolean(undetectable)
-    Node* r = R.ReduceUnop(op, Type::Undetectable());
-    R.CheckFalse(r);
-  }
-
-  {  // ToBoolean(object)
-    Node* r = R.ReduceUnop(op, Type::Object());
-    CHECK_EQ(IrOpcode::kAnyToBoolean, r->opcode());
-  }
-}
-
-
 TEST(JSToString1) {
   JSTypedLoweringTester R;
 
@@ -546,8 +553,7 @@
 
   {  // ToString(boolean)
     Node* r = R.ReduceUnop(op, Type::Boolean());
-    // TODO(titzer): could be a branch
-    CHECK_EQ(IrOpcode::kJSToString, r->opcode());
+    CHECK_EQ(IrOpcode::kSelect, r->opcode());
   }
 
   {  // ToString(number)
@@ -575,8 +581,9 @@
 
   for (size_t i = 0; i < arraysize(types); i++) {
     Node* n = R.Parameter(types[i]);
-    Node* c = R.graph.NewNode(R.javascript.ToString(), n, R.context(),
-                              R.start(), R.start());
+    Node* c =
+        R.graph.NewNode(R.javascript.ToString(), n, R.context(),
+                        R.EmptyFrameState(R.context()), R.start(), R.start());
     Node* effect_use = R.UseForEffect(c);
     Node* add = R.graph.NewNode(R.simplified.ReferenceEqual(Type::Any()), n, c);
 
@@ -596,14 +603,16 @@
 }
 
 
-TEST(StringComparison) {
+TEST_WITH_STRONG(StringComparison) {
   JSTypedLoweringTester R;
 
   const Operator* ops[] = {
-      R.javascript.LessThan(),           R.simplified.StringLessThan(),
-      R.javascript.LessThanOrEqual(),    R.simplified.StringLessThanOrEqual(),
-      R.javascript.GreaterThan(),        R.simplified.StringLessThan(),
-      R.javascript.GreaterThanOrEqual(), R.simplified.StringLessThanOrEqual()};
+      R.javascript.LessThan(language_mode), R.simplified.StringLessThan(),
+      R.javascript.LessThanOrEqual(language_mode),
+      R.simplified.StringLessThanOrEqual(),
+      R.javascript.GreaterThan(language_mode), R.simplified.StringLessThan(),
+      R.javascript.GreaterThanOrEqual(language_mode),
+      R.simplified.StringLessThanOrEqual()};
 
   for (size_t i = 0; i < arraysize(kStringTypes); i++) {
     Node* p0 = R.Parameter(kStringTypes[i], 0);
@@ -614,7 +623,7 @@
         Node* cmp = R.Binop(ops[k], p0, p1);
         Node* r = R.reduce(cmp);
 
-        R.CheckPureBinop(ops[k + 1], r);
+        R.CheckBinop(ops[k + 1], r);
         if (k >= 4) {
           // GreaterThan and GreaterThanOrEqual commute the inputs
           // and use the LessThan and LessThanOrEqual operators.
@@ -631,9 +640,9 @@
 
 
 static void CheckIsConvertedToNumber(Node* val, Node* converted) {
-  if (NodeProperties::GetBounds(val).upper->Is(Type::Number())) {
+  if (NodeProperties::GetType(val)->Is(Type::Number())) {
     CHECK_EQ(val, converted);
-  } else if (NodeProperties::GetBounds(val).upper->Is(Type::Boolean())) {
+  } else if (NodeProperties::GetType(val)->Is(Type::Boolean())) {
     CHECK_EQ(IrOpcode::kBooleanToNumber, converted->opcode());
     CHECK_EQ(val, converted->InputAt(0));
   } else {
@@ -644,14 +653,16 @@
 }
 
 
-TEST(NumberComparison) {
+TEST_WITH_STRONG(NumberComparison) {
   JSTypedLoweringTester R;
 
   const Operator* ops[] = {
-      R.javascript.LessThan(),           R.simplified.NumberLessThan(),
-      R.javascript.LessThanOrEqual(),    R.simplified.NumberLessThanOrEqual(),
-      R.javascript.GreaterThan(),        R.simplified.NumberLessThan(),
-      R.javascript.GreaterThanOrEqual(), R.simplified.NumberLessThanOrEqual()};
+      R.javascript.LessThan(language_mode), R.simplified.NumberLessThan(),
+      R.javascript.LessThanOrEqual(language_mode),
+      R.simplified.NumberLessThanOrEqual(),
+      R.javascript.GreaterThan(language_mode), R.simplified.NumberLessThan(),
+      R.javascript.GreaterThanOrEqual(language_mode),
+      R.simplified.NumberLessThanOrEqual()};
 
   Node* const p0 = R.Parameter(Type::Number(), 0);
   Node* const p1 = R.Parameter(Type::Number(), 1);
@@ -660,7 +671,7 @@
     Node* cmp = R.Binop(ops[k], p0, p1);
     Node* r = R.reduce(cmp);
 
-    R.CheckPureBinop(ops[k + 1], r);
+    R.CheckBinop(ops[k + 1], r);
     if (k >= 4) {
       // GreaterThan and GreaterThanOrEqual commute the inputs
       // and use the LessThan and LessThanOrEqual operators.
@@ -674,7 +685,7 @@
 }
 
 
-TEST(MixedComparison1) {
+TEST_WITH_STRONG(MixedComparison1) {
   JSTypedLoweringTester R;
 
   Type* types[] = {Type::Number(), Type::String(),
@@ -686,18 +697,20 @@
     for (size_t j = 0; j < arraysize(types); j++) {
       Node* p1 = R.Parameter(types[j], 1);
       {
-        Node* cmp = R.Binop(R.javascript.LessThan(), p0, p1);
+        const Operator* less_than = R.javascript.LessThan(language_mode);
+        Node* cmp = R.Binop(less_than, p0, p1);
         Node* r = R.reduce(cmp);
-
-        if (!types[i]->Maybe(Type::String()) ||
-            !types[j]->Maybe(Type::String())) {
-          if (types[i]->Is(Type::String()) && types[j]->Is(Type::String())) {
-            R.CheckPureBinop(R.simplified.StringLessThan(), r);
-          } else {
-            R.CheckPureBinop(R.simplified.NumberLessThan(), r);
-          }
+        if (types[i]->Is(Type::String()) && types[j]->Is(Type::String())) {
+          R.CheckBinop(R.simplified.StringLessThan(), r);
+        } else if ((types[i]->Is(Type::Number()) &&
+                    types[j]->Is(Type::Number())) ||
+                   (!is_strong(language_mode) &&
+                    (!types[i]->Maybe(Type::String()) ||
+                     !types[j]->Maybe(Type::String())))) {
+          R.CheckBinop(R.simplified.NumberLessThan(), r);
         } else {
-          CHECK_EQ(cmp, r);  // No reduction of mixed types.
+          // No reduction of mixed types.
+          CHECK_EQ(r->op(), less_than);
         }
       }
     }
@@ -705,27 +718,7 @@
 }
 
 
-TEST(UnaryNot) {
-  JSTypedLoweringTester R;
-  const Operator* opnot = R.javascript.UnaryNot();
-
-  for (size_t i = 0; i < arraysize(kJSTypes); i++) {
-    Node* orig = R.Unop(opnot, R.Parameter(kJSTypes[i]));
-    Node* r = R.reduce(orig);
-
-    if (r == orig && orig->opcode() == IrOpcode::kJSToBoolean) {
-      // The original node was turned into a ToBoolean.
-      CHECK_EQ(IrOpcode::kJSToBoolean, r->opcode());
-    } else if (r->opcode() != IrOpcode::kHeapConstant) {
-      CHECK_EQ(IrOpcode::kBooleanNot, r->opcode());
-    }
-  }
-}
-
-
-TEST(RemoveToNumberEffects) {
-  FLAG_turbo_deoptimization = true;
-
+TEST_WITH_STRONG(RemoveToNumberEffects) {
   JSTypedLoweringTester R;
 
   Node* effect_use = NULL;
@@ -737,21 +730,27 @@
 
     switch (i) {
       case 0:
+        CHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(
+                        R.javascript.ToNumber()));
         effect_use = R.graph.NewNode(R.javascript.ToNumber(), p0, R.context(),
-                                     ton, R.start());
+                                     frame_state, ton, R.start());
         break;
       case 1:
+        CHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(
+                        R.javascript.ToNumber()));
         effect_use = R.graph.NewNode(R.javascript.ToNumber(), ton, R.context(),
-                                     ton, R.start());
+                                     frame_state, ton, R.start());
         break;
       case 2:
         effect_use = R.graph.NewNode(R.common.EffectPhi(1), ton, R.start());
       case 3:
-        effect_use = R.graph.NewNode(R.javascript.Add(), ton, ton, R.context(),
+        effect_use = R.graph.NewNode(R.javascript.Add(language_mode, R.hints),
+                                     ton, ton, R.context(), frame_state,
                                      frame_state, ton, R.start());
         break;
       case 4:
-        effect_use = R.graph.NewNode(R.javascript.Add(), p0, p0, R.context(),
+        effect_use = R.graph.NewNode(R.javascript.Add(language_mode, R.hints),
+                                     p0, p0, R.context(), frame_state,
                                      frame_state, ton, R.start());
         break;
       case 5:
@@ -777,7 +776,7 @@
     }
   }
 
-  CHECK_EQ(NULL, effect_use);  // should have done all cases above.
+  CHECK(!effect_use);  // should have done all cases above.
 }
 
 
@@ -845,20 +844,21 @@
     Node* p1 = j == 1 ? l : r;
 
     {
-      Node* eq = strict ? R->graph.NewNode(R->javascript.StrictEqual(), p0, p1)
-                        : R->Binop(R->javascript.Equal(), p0, p1);
+      const Operator* op =
+          strict ? R->javascript.StrictEqual() : R->javascript.Equal();
+      Node* eq = R->Binop(op, p0, p1);
       Node* r = R->reduce(eq);
-      R->CheckPureBinop(expected, r);
+      R->CheckBinop(expected, r);
     }
 
     {
-      Node* ne = strict
-                     ? R->graph.NewNode(R->javascript.StrictNotEqual(), p0, p1)
-                     : R->Binop(R->javascript.NotEqual(), p0, p1);
+      const Operator* op =
+          strict ? R->javascript.StrictNotEqual() : R->javascript.NotEqual();
+      Node* ne = R->Binop(op, p0, p1);
       Node* n = R->reduce(ne);
       CHECK_EQ(IrOpcode::kBooleanNot, n->opcode());
       Node* r = n->InputAt(0);
-      R->CheckPureBinop(expected, r);
+      R->CheckBinop(expected, r);
     }
   }
 }
@@ -910,25 +910,33 @@
 }
 
 
-TEST(RemovePureNumberBinopEffects) {
+TEST_WITH_STRONG(RemovePureNumberBinopEffects) {
   JSTypedLoweringTester R;
 
   const Operator* ops[] = {
-      R.javascript.Equal(),           R.simplified.NumberEqual(),
-      R.javascript.Add(),             R.simplified.NumberAdd(),
-      R.javascript.Subtract(),        R.simplified.NumberSubtract(),
-      R.javascript.Multiply(),        R.simplified.NumberMultiply(),
-      R.javascript.Divide(),          R.simplified.NumberDivide(),
-      R.javascript.Modulus(),         R.simplified.NumberModulus(),
-      R.javascript.LessThan(),        R.simplified.NumberLessThan(),
-      R.javascript.LessThanOrEqual(), R.simplified.NumberLessThanOrEqual(),
+      R.javascript.Equal(),
+      R.simplified.NumberEqual(),
+      R.javascript.Add(language_mode, R.hints),
+      R.simplified.NumberAdd(),
+      R.javascript.Subtract(language_mode, R.hints),
+      R.simplified.NumberSubtract(),
+      R.javascript.Multiply(language_mode, R.hints),
+      R.simplified.NumberMultiply(),
+      R.javascript.Divide(language_mode, R.hints),
+      R.simplified.NumberDivide(),
+      R.javascript.Modulus(language_mode, R.hints),
+      R.simplified.NumberModulus(),
+      R.javascript.LessThan(language_mode),
+      R.simplified.NumberLessThan(),
+      R.javascript.LessThanOrEqual(language_mode),
+      R.simplified.NumberLessThanOrEqual(),
   };
 
   for (size_t j = 0; j < arraysize(ops); j += 2) {
     BinopEffectsTester B(ops[j], Type::Number(), Type::Number());
     CHECK_EQ(ops[j + 1]->opcode(), B.result->op()->opcode());
 
-    B.R.CheckPureBinop(B.result->opcode(), B.result);
+    B.R.CheckBinop(B.result->opcode(), B.result);
 
     B.CheckNoOp(0);
     B.CheckNoOp(1);
@@ -942,10 +950,12 @@
   JSTypedLoweringTester R;
 
   const Operator* ops[] = {
-      R.javascript.Subtract(), R.simplified.NumberSubtract(),
-      R.javascript.Multiply(), R.simplified.NumberMultiply(),
-      R.javascript.Divide(),   R.simplified.NumberDivide(),
-      R.javascript.Modulus(),  R.simplified.NumberModulus(),
+      R.javascript.Subtract(LanguageMode::SLOPPY, R.hints),
+      R.simplified.NumberSubtract(),
+      R.javascript.Multiply(LanguageMode::SLOPPY, R.hints),
+      R.simplified.NumberMultiply(),
+      R.javascript.Divide(LanguageMode::SLOPPY, R.hints),
+      R.simplified.NumberDivide(),
   };
 
   for (size_t j = 0; j < arraysize(ops); j += 2) {
@@ -968,11 +978,14 @@
   JSTypedLoweringTester R;
 
   const Operator* ops[] = {
-      R.javascript.Add(),      R.simplified.NumberAdd(),
-      R.javascript.Subtract(), R.simplified.NumberSubtract(),
-      R.javascript.Multiply(), R.simplified.NumberMultiply(),
-      R.javascript.Divide(),   R.simplified.NumberDivide(),
-      R.javascript.Modulus(),  R.simplified.NumberModulus(),
+      R.javascript.Add(LanguageMode::SLOPPY, R.hints),
+      R.simplified.NumberAdd(),
+      R.javascript.Subtract(LanguageMode::SLOPPY, R.hints),
+      R.simplified.NumberSubtract(),
+      R.javascript.Multiply(LanguageMode::SLOPPY, R.hints),
+      R.simplified.NumberMultiply(),
+      R.javascript.Divide(LanguageMode::SLOPPY, R.hints),
+      R.simplified.NumberDivide(),
   };
 
   for (size_t j = 0; j < arraysize(ops); j += 2) {
@@ -1007,8 +1020,10 @@
   JSTypedLoweringTester R;
 
   const Operator* ops[] = {
-      R.javascript.GreaterThan(), R.simplified.NumberLessThan(),
-      R.javascript.GreaterThanOrEqual(), R.simplified.NumberLessThanOrEqual(),
+      R.javascript.GreaterThan(LanguageMode::SLOPPY),
+      R.simplified.NumberLessThan(),
+      R.javascript.GreaterThanOrEqual(LanguageMode::SLOPPY),
+      R.simplified.NumberLessThanOrEqual(),
   };
 
   for (size_t j = 0; j < arraysize(ops); j += 2) {
@@ -1055,14 +1070,13 @@
 
 
 TEST(Int32BinopEffects) {
-  JSBitwiseTypedLoweringTester R;
-
+  JSBitwiseTypedLoweringTester R(LanguageMode::SLOPPY);
   for (int j = 0; j < R.kNumberOps; j += 2) {
     bool signed_left = R.signedness[j], signed_right = R.signedness[j + 1];
     BinopEffectsTester B(R.ops[j], I32Type(signed_left), I32Type(signed_right));
     CHECK_EQ(R.ops[j + 1]->opcode(), B.result->op()->opcode());
 
-    B.R.CheckPureBinop(B.result->opcode(), B.result);
+    B.R.CheckBinop(B.result->opcode(), B.result);
 
     B.CheckNoOp(0);
     B.CheckNoOp(1);
@@ -1075,7 +1089,7 @@
     BinopEffectsTester B(R.ops[j], Type::Number(), Type::Number());
     CHECK_EQ(R.ops[j + 1]->opcode(), B.result->op()->opcode());
 
-    B.R.CheckPureBinop(B.result->opcode(), B.result);
+    B.R.CheckBinop(B.result->opcode(), B.result);
 
     B.CheckConvertedInput(NumberToI32(signed_left), 0, false);
     B.CheckConvertedInput(NumberToI32(signed_right), 1, false);
@@ -1087,7 +1101,7 @@
     bool signed_left = R.signedness[j], signed_right = R.signedness[j + 1];
     BinopEffectsTester B(R.ops[j], Type::Number(), Type::Primitive());
 
-    B.R.CheckPureBinop(B.result->opcode(), B.result);
+    B.R.CheckBinop(B.result->opcode(), B.result);
 
     Node* i0 = B.CheckConvertedInput(NumberToI32(signed_left), 0, false);
     Node* i1 = B.CheckConvertedInput(NumberToI32(signed_right), 1, false);
@@ -1104,7 +1118,7 @@
     bool signed_left = R.signedness[j], signed_right = R.signedness[j + 1];
     BinopEffectsTester B(R.ops[j], Type::Primitive(), Type::Number());
 
-    B.R.CheckPureBinop(B.result->opcode(), B.result);
+    B.R.CheckBinop(B.result->opcode(), B.result);
 
     Node* i0 = B.CheckConvertedInput(NumberToI32(signed_left), 0, false);
     Node* i1 = B.CheckConvertedInput(NumberToI32(signed_right), 1, false);
@@ -1121,7 +1135,7 @@
     bool signed_left = R.signedness[j], signed_right = R.signedness[j + 1];
     BinopEffectsTester B(R.ops[j], Type::Primitive(), Type::Primitive());
 
-    B.R.CheckPureBinop(B.result->opcode(), B.result);
+    B.R.CheckBinop(B.result->opcode(), B.result);
 
     Node* i0 = B.CheckConvertedInput(NumberToI32(signed_left), 0, false);
     Node* i1 = B.CheckConvertedInput(NumberToI32(signed_right), 1, false);
@@ -1137,9 +1151,9 @@
 }
 
 
-TEST(Int32AddNarrowing) {
+TEST_WITH_STRONG(Int32AddNarrowing) {
   {
-    JSBitwiseTypedLoweringTester R;
+    JSBitwiseTypedLoweringTester R(language_mode);
 
     for (int o = 0; o < R.kNumberOps; o += 2) {
       for (size_t i = 0; i < arraysize(kInt32Types); i++) {
@@ -1162,7 +1176,7 @@
     }
   }
   {
-    JSBitwiseShiftTypedLoweringTester R;
+    JSBitwiseShiftTypedLoweringTester R(language_mode);
 
     for (int o = 0; o < R.kNumberOps; o += 2) {
       for (size_t i = 0; i < arraysize(kInt32Types); i++) {
@@ -1185,7 +1199,7 @@
     }
   }
   {
-    JSBitwiseTypedLoweringTester R;
+    JSBitwiseTypedLoweringTester R(language_mode);
 
     for (int o = 0; o < R.kNumberOps; o += 2) {
       Node* n0 = R.Parameter(I32Type(R.signedness[o]));
@@ -1209,7 +1223,7 @@
 }
 
 
-TEST(Int32Comparisons) {
+TEST_WITH_STRONG(Int32Comparisons) {
   JSTypedLoweringTester R;
 
   struct Entry {
@@ -1221,16 +1235,17 @@
   };
 
   Entry ops[] = {
-      {R.javascript.LessThan(), R.machine.Uint32LessThan(),
+      {R.javascript.LessThan(language_mode), R.machine.Uint32LessThan(),
        R.machine.Int32LessThan(), R.simplified.NumberLessThan(), false},
-      {R.javascript.LessThanOrEqual(), R.machine.Uint32LessThanOrEqual(),
-       R.machine.Int32LessThanOrEqual(), R.simplified.NumberLessThanOrEqual(),
-       false},
-      {R.javascript.GreaterThan(), R.machine.Uint32LessThan(),
+      {R.javascript.LessThanOrEqual(language_mode),
+       R.machine.Uint32LessThanOrEqual(), R.machine.Int32LessThanOrEqual(),
+       R.simplified.NumberLessThanOrEqual(), false},
+      {R.javascript.GreaterThan(language_mode), R.machine.Uint32LessThan(),
        R.machine.Int32LessThan(), R.simplified.NumberLessThan(), true},
-      {R.javascript.GreaterThanOrEqual(), R.machine.Uint32LessThanOrEqual(),
-       R.machine.Int32LessThanOrEqual(), R.simplified.NumberLessThanOrEqual(),
-       true}};
+      {R.javascript.GreaterThanOrEqual(language_mode),
+       R.machine.Uint32LessThanOrEqual(), R.machine.Int32LessThanOrEqual(),
+       R.simplified.NumberLessThanOrEqual(), true}
+  };
 
   for (size_t o = 0; o < arraysize(ops); o++) {
     for (size_t i = 0; i < arraysize(kNumberTypes); i++) {
@@ -1252,7 +1267,7 @@
         } else {
           expected = ops[o].num_op;
         }
-        R.CheckPureBinop(expected, r);
+        R.CheckBinop(expected, r);
         if (ops[o].commute) {
           CHECK_EQ(p1, r->InputAt(0));
           CHECK_EQ(p0, r->InputAt(1));
@@ -1264,3 +1279,7 @@
     }
   }
 }
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/test/cctest/compiler/test-jump-threading.cc b/test/cctest/compiler/test-jump-threading.cc
index 74bf43d..8c02012 100644
--- a/test/cctest/compiler/test-jump-threading.cc
+++ b/test/cctest/compiler/test-jump-threading.cc
@@ -2,25 +2,21 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "src/v8.h"
-#include "test/cctest/cctest.h"
-
 #include "src/compiler/instruction.h"
 #include "src/compiler/instruction-codes.h"
 #include "src/compiler/jump-threading.h"
+#include "test/cctest/cctest.h"
 
 namespace v8 {
 namespace internal {
 namespace compiler {
 
-typedef BasicBlock::RpoNumber RpoNumber;
-
 class TestCode : public HandleAndZoneScope {
  public:
   TestCode()
       : HandleAndZoneScope(),
         blocks_(main_zone()),
-        sequence_(main_zone(), &blocks_),
+        sequence_(main_isolate(), main_zone(), &blocks_),
         rpo_number_(RpoNumber::FromInt(0)),
         current_(NULL) {}
 
@@ -31,9 +27,9 @@
 
   int Jump(int target) {
     Start();
-    InstructionOperand* ops[] = {UseRpo(target)};
-    sequence_.AddInstruction(Instruction::New(main_zone(), kArchJmp, 0, NULL, 1,
-                                              ops, 0, NULL)->MarkAsControl());
+    InstructionOperand ops[] = {UseRpo(target)};
+    sequence_.AddInstruction(
+        Instruction::New(main_zone(), kArchJmp, 0, NULL, 1, ops, 0, NULL));
     int pos = static_cast<int>(sequence_.instructions().size() - 1);
     End();
     return pos;
@@ -44,11 +40,11 @@
   }
   int Branch(int ttarget, int ftarget) {
     Start();
-    InstructionOperand* ops[] = {UseRpo(ttarget), UseRpo(ftarget)};
+    InstructionOperand ops[] = {UseRpo(ttarget), UseRpo(ftarget)};
     InstructionCode code = 119 | FlagsModeField::encode(kFlags_branch) |
                            FlagsConditionField::encode(kEqual);
-    sequence_.AddInstruction(Instruction::New(main_zone(), code, 0, NULL, 2,
-                                              ops, 0, NULL)->MarkAsControl());
+    sequence_.AddInstruction(
+        Instruction::New(main_zone(), code, 0, NULL, 2, ops, 0, NULL));
     int pos = static_cast<int>(sequence_.instructions().size() - 1);
     End();
     return pos;
@@ -61,15 +57,18 @@
     Start();
     sequence_.AddInstruction(Instruction::New(main_zone(), kArchNop));
     int index = static_cast<int>(sequence_.instructions().size()) - 1;
-    sequence_.AddGapMove(index, RegisterOperand::Create(13, main_zone()),
-                         RegisterOperand::Create(13, main_zone()));
+    AddGapMove(index, AllocatedOperand(LocationOperand::REGISTER,
+                                       MachineRepresentation::kWord32, 13),
+               AllocatedOperand(LocationOperand::REGISTER,
+                                MachineRepresentation::kWord32, 13));
   }
   void NonRedundantMoves() {
     Start();
     sequence_.AddInstruction(Instruction::New(main_zone(), kArchNop));
     int index = static_cast<int>(sequence_.instructions().size()) - 1;
-    sequence_.AddGapMove(index, ImmediateOperand::Create(11, main_zone()),
-                         RegisterOperand::Create(11, main_zone()));
+    AddGapMove(index, ConstantOperand(11),
+               AllocatedOperand(LocationOperand::REGISTER,
+                                MachineRepresentation::kWord32, 11));
   }
   void Other() {
     Start();
@@ -81,15 +80,14 @@
     current_ = NULL;
     rpo_number_ = RpoNumber::FromInt(rpo_number_.ToInt() + 1);
   }
-  InstructionOperand* UseRpo(int num) {
-    int index = sequence_.AddImmediate(Constant(RpoNumber::FromInt(num)));
-    return ImmediateOperand::Create(index, main_zone());
+  InstructionOperand UseRpo(int num) {
+    return sequence_.AddImmediate(Constant(RpoNumber::FromInt(num)));
   }
   void Start(bool deferred = false) {
     if (current_ == NULL) {
-      current_ = new (main_zone()) InstructionBlock(
-          main_zone(), BasicBlock::Id::FromInt(rpo_number_.ToInt()),
-          rpo_number_, RpoNumber::Invalid(), RpoNumber::Invalid(), deferred);
+      current_ = new (main_zone())
+          InstructionBlock(main_zone(), rpo_number_, RpoNumber::Invalid(),
+                           RpoNumber::Invalid(), deferred, false);
       blocks_.push_back(current_);
       sequence_.StartBlock(rpo_number_);
     }
@@ -98,11 +96,17 @@
     CHECK(current_ == NULL);
     Start(true);
   }
+  void AddGapMove(int index, const InstructionOperand& from,
+                  const InstructionOperand& to) {
+    sequence_.InstructionAt(index)
+        ->GetOrCreateParallelMove(Instruction::START, main_zone())
+        ->AddMove(from, to);
+  }
 };
 
 
 void VerifyForwarding(TestCode& code, int count, int* expected) {
-  Zone local_zone(code.main_isolate());
+  Zone local_zone;
   ZoneVector<RpoNumber> result(&local_zone);
   JumpThreading::ComputeForwarding(&local_zone, result, &code.sequence_);
 
diff --git a/test/cctest/compiler/test-linkage.cc b/test/cctest/compiler/test-linkage.cc
index 117caf2..939b144 100644
--- a/test/cctest/compiler/test-linkage.cc
+++ b/test/cctest/compiler/test-linkage.cc
@@ -2,9 +2,9 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "src/v8.h"
-
+#include "src/code-stubs.h"
 #include "src/compiler.h"
+#include "src/parsing/parser.h"
 #include "src/zone.h"
 
 #include "src/compiler/common-operator.h"
@@ -17,10 +17,9 @@
 #include "src/compiler/schedule.h"
 #include "test/cctest/cctest.h"
 
-#if V8_TURBOFAN_TARGET
-
-using namespace v8::internal;
-using namespace v8::internal::compiler;
+namespace v8 {
+namespace internal {
+namespace compiler {
 
 static Operator dummy_operator(IrOpcode::kParameter, Operator::kNoWrite,
                                "dummy", 0, 0, 0, 0, 0, 0);
@@ -32,37 +31,37 @@
                                    ->NewStringFromUtf8(CStrVector(source))
                                    .ToHandleChecked();
   Handle<SharedFunctionInfo> shared_function = Compiler::CompileScript(
-      source_code, Handle<String>(), 0, 0, false,
-      Handle<Context>(isolate->native_context()), NULL, NULL,
-      v8::ScriptCompiler::kNoCompileOptions, NOT_NATIVES_CODE);
+      source_code, Handle<String>(), 0, 0, v8::ScriptOriginOptions(),
+      Handle<Object>(), Handle<Context>(isolate->native_context()), NULL, NULL,
+      v8::ScriptCompiler::kNoCompileOptions, NOT_NATIVES_CODE, false);
   return isolate->factory()->NewFunctionFromSharedFunctionInfo(
       shared_function, isolate->native_context());
 }
 
 
 TEST(TestLinkageCreate) {
-  InitializedHandleScope handles;
+  HandleAndZoneScope handles;
   Handle<JSFunction> function = Compile("a + b");
-  CompilationInfoWithZone info(function);
-  Linkage linkage(info.zone(), &info);
+  ParseInfo parse_info(handles.main_zone(), function);
+  CompilationInfo info(&parse_info);
+  CallDescriptor* descriptor = Linkage::ComputeIncoming(info.zone(), &info);
+  CHECK(descriptor);
 }
 
 
 TEST(TestLinkageJSFunctionIncoming) {
-  InitializedHandleScope handles;
-
   const char* sources[] = {"(function() { })", "(function(a) { })",
                            "(function(a,b) { })", "(function(a,b,c) { })"};
 
   for (int i = 0; i < 3; i++) {
-    i::HandleScope handles(CcTest::i_isolate());
-    Handle<JSFunction> function = v8::Utils::OpenHandle(
-        *v8::Handle<v8::Function>::Cast(CompileRun(sources[i])));
-    CompilationInfoWithZone info(function);
-    Linkage linkage(info.zone(), &info);
-
-    CallDescriptor* descriptor = linkage.GetIncomingDescriptor();
-    CHECK_NE(NULL, descriptor);
+    HandleAndZoneScope handles;
+    Handle<JSFunction> function =
+        Handle<JSFunction>::cast(v8::Utils::OpenHandle(
+            *v8::Local<v8::Function>::Cast(CompileRun(sources[i]))));
+    ParseInfo parse_info(handles.main_zone(), function);
+    CompilationInfo info(&parse_info);
+    CallDescriptor* descriptor = Linkage::ComputeIncoming(info.zone(), &info);
+    CHECK(descriptor);
 
     CHECK_EQ(1 + i, static_cast<int>(descriptor->JSParameterCount()));
     CHECK_EQ(1, static_cast<int>(descriptor->ReturnCount()));
@@ -74,24 +73,28 @@
 
 TEST(TestLinkageCodeStubIncoming) {
   Isolate* isolate = CcTest::InitIsolateOnce();
-  CompilationInfoWithZone info(static_cast<HydrogenCodeStub*>(NULL), isolate);
-  Linkage linkage(info.zone(), &info);
-  // TODO(titzer): test linkage creation with a bonafide code stub.
-  // this just checks current behavior.
-  CHECK_EQ(NULL, linkage.GetIncomingDescriptor());
+  Zone zone;
+  ToNumberStub stub(isolate);
+  CompilationInfo info(&stub, isolate, &zone);
+  CallDescriptor* descriptor = Linkage::ComputeIncoming(&zone, &info);
+  CHECK(descriptor);
+  CHECK_EQ(0, static_cast<int>(descriptor->StackParameterCount()));
+  CHECK_EQ(1, static_cast<int>(descriptor->ReturnCount()));
+  CHECK_EQ(Operator::kNoProperties, descriptor->properties());
+  CHECK_EQ(false, descriptor->IsJSFunctionCall());
 }
 
 
 TEST(TestLinkageJSCall) {
   HandleAndZoneScope handles;
   Handle<JSFunction> function = Compile("a + c");
-  CompilationInfoWithZone info(function);
-  Linkage linkage(info.zone(), &info);
+  ParseInfo parse_info(handles.main_zone(), function);
+  CompilationInfo info(&parse_info);
 
   for (int i = 0; i < 32; i++) {
-    CallDescriptor* descriptor =
-        linkage.GetJSCallDescriptor(i, CallDescriptor::kNoFlags);
-    CHECK_NE(NULL, descriptor);
+    CallDescriptor* descriptor = Linkage::GetJSCallDescriptor(
+        info.zone(), false, i, CallDescriptor::kNoFlags);
+    CHECK(descriptor);
     CHECK_EQ(i, static_cast<int>(descriptor->JSParameterCount()));
     CHECK_EQ(1, static_cast<int>(descriptor->ReturnCount()));
     CHECK_EQ(Operator::kNoProperties, descriptor->properties());
@@ -109,5 +112,6 @@
   // TODO(titzer): test linkage creation for outgoing stub calls.
 }
 
-
-#endif  // V8_TURBOFAN_TARGET
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/test/cctest/compiler/test-loop-analysis.cc b/test/cctest/compiler/test-loop-analysis.cc
index 9c11268..68bfc28 100644
--- a/test/cctest/compiler/test-loop-analysis.cc
+++ b/test/cctest/compiler/test-loop-analysis.cc
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "src/v8.h"
-
 #include "src/compiler/access-builder.h"
 #include "src/compiler/common-operator.h"
 #include "src/compiler/graph.h"
@@ -20,14 +18,15 @@
 #include "src/compiler/verifier.h"
 #include "test/cctest/cctest.h"
 
-using namespace v8::internal;
-using namespace v8::internal::compiler;
+namespace v8 {
+namespace internal {
+namespace compiler {
 
 static Operator kIntAdd(IrOpcode::kInt32Add, Operator::kPure, "Int32Add", 2, 0,
                         0, 1, 0, 0);
 static Operator kIntLt(IrOpcode::kInt32LessThan, Operator::kPure,
                        "Int32LessThan", 2, 0, 0, 1, 0, 0);
-static Operator kStore(IrOpcode::kStore, Operator::kNoProperties, "Store", 0, 2,
+static Operator kStore(IrOpcode::kStore, Operator::kNoProperties, "Store", 1, 1,
                        1, 0, 1, 0);
 
 static const int kNumLeafs = 4;
@@ -39,9 +38,9 @@
       : isolate(main_isolate()),
         common(main_zone()),
         graph(main_zone()),
-        jsgraph(&graph, &common, NULL, NULL),
+        jsgraph(main_isolate(), &graph, &common, nullptr, nullptr, nullptr),
         start(graph.NewNode(common.Start(1))),
-        end(graph.NewNode(common.End(), start)),
+        end(graph.NewNode(common.End(1), start)),
         p0(graph.NewNode(common.Parameter(0), start)),
         zero(jsgraph.Int32Constant(0)),
         one(jsgraph.OneConstant()),
@@ -112,7 +111,8 @@
   }
 
   const Operator* op(int count, bool effect) {
-    return effect ? common.EffectPhi(count) : common.Phi(kMachAnyTagged, count);
+    return effect ? common.EffectPhi(count)
+                  : common.Phi(MachineRepresentation::kTagged, count);
   }
 
   Node* Return(Node* val, Node* effect, Node* control) {
@@ -127,7 +127,7 @@
         OFStream os(stdout);
         os << AsRPO(graph);
       }
-      Zone zone(isolate);
+      Zone zone;
       loop_tree = LoopFinder::BuildLoopTree(&graph, &zone);
     }
     return loop_tree;
@@ -136,7 +136,7 @@
   void CheckLoop(Node** header, int header_count, Node** body, int body_count) {
     LoopTree* tree = GetLoopTree();
     LoopTree::Loop* loop = tree->ContainingLoop(header[0]);
-    CHECK_NE(NULL, loop);
+    CHECK(loop);
 
     CHECK(header_count == static_cast<int>(loop->HeaderSize()));
     for (int i = 0; i < header_count; i++) {
@@ -146,6 +146,7 @@
     }
 
     CHECK_EQ(body_count, static_cast<int>(loop->BodySize()));
+    // TODO(turbofan): O(n^2) set equivalence in this test.
     for (int i = 0; i < body_count; i++) {
       // Each body node should be contained in the loop.
       CHECK(tree->Contains(loop, body[i]));
@@ -154,7 +155,6 @@
   }
 
   void CheckRangeContains(NodeRange range, Node* node) {
-    // O(n) ftw.
     CHECK_NE(range.end(), std::find(range.begin(), range.end(), node));
   }
 
@@ -164,7 +164,7 @@
       Node* header = chain[i];
       // Each header should be in a loop.
       LoopTree::Loop* loop = tree->ContainingLoop(header);
-      CHECK_NE(NULL, loop);
+      CHECK(loop);
       // Check parentage.
       LoopTree::Loop* parent =
           i == 0 ? NULL : tree->ContainingLoop(chain[i - 1]);
@@ -178,6 +178,8 @@
       }
     }
   }
+
+  Zone* zone() { return main_zone(); }
 };
 
 
@@ -232,8 +234,7 @@
   Node* store;
 
   explicit StoreLoop(While& w)
-      : base(w.t.jsgraph.Int32Constant(12)),
-        val(w.t.jsgraph.Int32Constant(13)) {
+      : base(w.t.graph.start()), val(w.t.jsgraph.Int32Constant(13)) {
     Build(w);
   }
 
@@ -241,7 +242,7 @@
 
   void Build(While& w) {
     phi = w.t.graph.NewNode(w.t.op(2, true), base, base, w.loop);
-    store = w.t.graph.NewNode(&kStore, phi, val, w.loop);
+    store = w.t.graph.NewNode(&kStore, val, phi, w.loop);
     phi->ReplaceInput(1, store);
   }
 };
@@ -262,6 +263,23 @@
 }
 
 
+TEST(LaLoop1phi) {
+  // One loop with a simple phi.
+  LoopFinderTester t;
+  While w(t, t.p0);
+  Node* phi = t.graph.NewNode(t.common.Phi(MachineRepresentation::kTagged, 2),
+                              t.zero, t.one, w.loop);
+  t.Return(phi, t.start, w.exit);
+
+  Node* chain[] = {w.loop};
+  t.CheckNestedLoops(chain, 1);
+
+  Node* header[] = {w.loop, phi};
+  Node* body[] = {w.branch, w.if_true};
+  t.CheckLoop(header, 2, body, 2);
+}
+
+
 TEST(LaLoop1c) {
   // One loop with a counter.
   LoopFinderTester t;
@@ -451,6 +469,41 @@
 }
 
 
+TEST(LaNestedLoop1x) {
+  // One loop nested in another.
+  LoopFinderTester t;
+  While w1(t, t.p0);
+  While w2(t, t.p0);
+  w2.nest(w1);
+
+  const Operator* op = t.common.Phi(MachineRepresentation::kWord32, 2);
+  Node* p1a = t.graph.NewNode(op, t.p0, t.p0, w1.loop);
+  Node* p1b = t.graph.NewNode(op, t.p0, t.p0, w1.loop);
+  Node* p2a = t.graph.NewNode(op, p1a, t.p0, w2.loop);
+  Node* p2b = t.graph.NewNode(op, p1b, t.p0, w2.loop);
+
+  p1a->ReplaceInput(1, p2b);
+  p1b->ReplaceInput(1, p2a);
+
+  p2a->ReplaceInput(1, p2b);
+  p2b->ReplaceInput(1, p2a);
+
+  t.Return(t.p0, t.start, w1.exit);
+
+  Node* chain[] = {w1.loop, w2.loop};
+  t.CheckNestedLoops(chain, 2);
+
+  Node* h1[] = {w1.loop, p1a, p1b};
+  Node* b1[] = {w1.branch, w1.if_true, w2.loop,    p2a,
+                p2b,       w2.branch,  w2.if_true, w2.exit};
+  t.CheckLoop(h1, 3, b1, 8);
+
+  Node* h2[] = {w2.loop, p2a, p2b};
+  Node* b2[] = {w2.branch, w2.if_true};
+  t.CheckLoop(h2, 3, b2, 2);
+}
+
+
 TEST(LaNestedLoop2) {
   // Two loops nested in an outer loop.
   LoopFinderTester t;
@@ -636,8 +689,8 @@
         Node* p3 = t.jsgraph.Int32Constant(33);
 
         Node* loop = t.graph.NewNode(t.common.Loop(2), t.start, t.start);
-        Node* phi =
-            t.graph.NewNode(t.common.Phi(kMachInt32, 2), t.one, p1, loop);
+        Node* phi = t.graph.NewNode(
+            t.common.Phi(MachineRepresentation::kWord32, 2), t.one, p1, loop);
         Node* cond = t.graph.NewNode(&kIntAdd, phi, p2);
         Node* branch = t.graph.NewNode(t.common.Branch(), cond, loop);
         Node* if_true = t.graph.NewNode(t.common.IfTrue(), branch);
@@ -661,7 +714,7 @@
 
 
 void RunEdgeMatrix2(int i) {
-  DCHECK(i >= 0 && i < 5);
+  CHECK(i >= 0 && i < 5);
   for (int j = 0; j < 5; j++) {
     for (int k = 0; k < 5; k++) {
       LoopFinderTester t;
@@ -672,8 +725,8 @@
 
       // outer loop.
       Node* loop1 = t.graph.NewNode(t.common.Loop(2), t.start, t.start);
-      Node* phi1 =
-          t.graph.NewNode(t.common.Phi(kMachInt32, 2), t.one, p1, loop1);
+      Node* phi1 = t.graph.NewNode(
+          t.common.Phi(MachineRepresentation::kWord32, 2), t.one, p1, loop1);
       Node* cond1 = t.graph.NewNode(&kIntAdd, phi1, t.one);
       Node* branch1 = t.graph.NewNode(t.common.Branch(), cond1, loop1);
       Node* if_true1 = t.graph.NewNode(t.common.IfTrue(), branch1);
@@ -681,8 +734,8 @@
 
       // inner loop.
       Node* loop2 = t.graph.NewNode(t.common.Loop(2), if_true1, t.start);
-      Node* phi2 =
-          t.graph.NewNode(t.common.Phi(kMachInt32, 2), t.one, p2, loop2);
+      Node* phi2 = t.graph.NewNode(
+          t.common.Phi(MachineRepresentation::kWord32, 2), t.one, p2, loop2);
       Node* cond2 = t.graph.NewNode(&kIntAdd, phi2, p3);
       Node* branch2 = t.graph.NewNode(t.common.Branch(), cond2, loop2);
       Node* if_true2 = t.graph.NewNode(t.common.IfTrue(), branch2);
@@ -748,7 +801,8 @@
 
   // L1 depth = 0
   Node* loop1 = t.graph.NewNode(t.common.Loop(2), t.start, t.start);
-  Node* phi1 = t.graph.NewNode(t.common.Phi(kMachInt32, 2), p1a, p1c, loop1);
+  Node* phi1 = t.graph.NewNode(t.common.Phi(MachineRepresentation::kWord32, 2),
+                               p1a, p1c, loop1);
   Node* cond1 = t.graph.NewNode(&kIntAdd, phi1, p1b);
   Node* branch1 = t.graph.NewNode(t.common.Branch(), cond1, loop1);
   Node* if_true1 = t.graph.NewNode(t.common.IfTrue(), branch1);
@@ -756,7 +810,8 @@
 
   // L2 depth = 1
   Node* loop2 = t.graph.NewNode(t.common.Loop(2), if_true1, t.start);
-  Node* phi2 = t.graph.NewNode(t.common.Phi(kMachInt32, 2), p2a, p2c, loop2);
+  Node* phi2 = t.graph.NewNode(t.common.Phi(MachineRepresentation::kWord32, 2),
+                               p2a, p2c, loop2);
   Node* cond2 = t.graph.NewNode(&kIntAdd, phi2, p2b);
   Node* branch2 = t.graph.NewNode(t.common.Branch(), cond2, loop2);
   Node* if_true2 = t.graph.NewNode(t.common.IfTrue(), branch2);
@@ -764,7 +819,8 @@
 
   // L3 depth = 2
   Node* loop3 = t.graph.NewNode(t.common.Loop(2), if_true2, t.start);
-  Node* phi3 = t.graph.NewNode(t.common.Phi(kMachInt32, 2), p3a, p3c, loop3);
+  Node* phi3 = t.graph.NewNode(t.common.Phi(MachineRepresentation::kWord32, 2),
+                               p3a, p3c, loop3);
   Node* cond3 = t.graph.NewNode(&kIntAdd, phi3, p3b);
   Node* branch3 = t.graph.NewNode(t.common.Branch(), cond3, loop3);
   Node* if_true3 = t.graph.NewNode(t.common.IfTrue(), branch3);
@@ -822,7 +878,7 @@
 
 
 // Runs all combinations with a fixed {i}.
-void RunEdgeMatrix3_i(int i) {
+static void RunEdgeMatrix3_i(int i) {
   for (int a = 0; a < 1; a++) {
     for (int b = 0; b < 1; b++) {
       for (int c = 0; c < 4; c++) {
@@ -860,3 +916,108 @@
 
 
 TEST(LaEdgeMatrix3_5) { RunEdgeMatrix3_i(5); }
+
+
+static void RunManyChainedLoops_i(int count) {
+  LoopFinderTester t;
+  Node** nodes = t.zone()->NewArray<Node*>(count * 4);
+  Node* k11 = t.jsgraph.Int32Constant(11);
+  Node* k12 = t.jsgraph.Int32Constant(12);
+  Node* last = t.start;
+
+  // Build loops.
+  for (int i = 0; i < count; i++) {
+    Node* loop = t.graph.NewNode(t.common.Loop(2), last, t.start);
+    Node* phi = t.graph.NewNode(t.common.Phi(MachineRepresentation::kWord32, 2),
+                                k11, k12, loop);
+    Node* branch = t.graph.NewNode(t.common.Branch(), phi, loop);
+    Node* if_true = t.graph.NewNode(t.common.IfTrue(), branch);
+    Node* exit = t.graph.NewNode(t.common.IfFalse(), branch);
+    loop->ReplaceInput(1, if_true);
+
+    nodes[i * 4 + 0] = loop;
+    nodes[i * 4 + 1] = phi;
+    nodes[i * 4 + 2] = branch;
+    nodes[i * 4 + 3] = if_true;
+
+    last = exit;
+  }
+
+  Node* ret = t.graph.NewNode(t.common.Return(), t.p0, t.start, last);
+  t.graph.SetEnd(ret);
+
+  // Verify loops.
+  for (int i = 0; i < count; i++) {
+    t.CheckLoop(nodes + i * 4, 2, nodes + i * 4 + 2, 2);
+  }
+}
+
+
+static void RunManyNestedLoops_i(int count) {
+  LoopFinderTester t;
+  Node** nodes = t.zone()->NewArray<Node*>(count * 5);
+  Node* k11 = t.jsgraph.Int32Constant(11);
+  Node* k12 = t.jsgraph.Int32Constant(12);
+  Node* outer = nullptr;
+  Node* entry = t.start;
+
+  // Build loops.
+  for (int i = 0; i < count; i++) {
+    Node* loop = t.graph.NewNode(t.common.Loop(2), entry, t.start);
+    Node* phi = t.graph.NewNode(t.common.Phi(MachineRepresentation::kWord32, 2),
+                                k11, k12, loop);
+    Node* branch = t.graph.NewNode(t.common.Branch(), phi, loop);
+    Node* if_true = t.graph.NewNode(t.common.IfTrue(), branch);
+    Node* exit = t.graph.NewNode(t.common.IfFalse(), branch);
+
+    nodes[i * 5 + 0] = exit;     // outside
+    nodes[i * 5 + 1] = loop;     // header
+    nodes[i * 5 + 2] = phi;      // header
+    nodes[i * 5 + 3] = branch;   // body
+    nodes[i * 5 + 4] = if_true;  // body
+
+    if (outer != nullptr) {
+      // inner loop.
+      outer->ReplaceInput(1, exit);
+    } else {
+      // outer loop.
+      Node* ret = t.graph.NewNode(t.common.Return(), t.p0, t.start, exit);
+      t.graph.SetEnd(ret);
+    }
+    outer = loop;
+    entry = if_true;
+  }
+  outer->ReplaceInput(1, entry);  // innermost loop.
+
+  // Verify loops.
+  for (int i = 0; i < count; i++) {
+    int k = i * 5;
+    t.CheckLoop(nodes + k + 1, 2, nodes + k + 3, count * 5 - k - 3);
+  }
+}
+
+
+TEST(LaManyChained_30) { RunManyChainedLoops_i(30); }
+TEST(LaManyChained_31) { RunManyChainedLoops_i(31); }
+TEST(LaManyChained_32) { RunManyChainedLoops_i(32); }
+TEST(LaManyChained_33) { RunManyChainedLoops_i(33); }
+TEST(LaManyChained_34) { RunManyChainedLoops_i(34); }
+TEST(LaManyChained_62) { RunManyChainedLoops_i(62); }
+TEST(LaManyChained_63) { RunManyChainedLoops_i(63); }
+TEST(LaManyChained_64) { RunManyChainedLoops_i(64); }
+
+TEST(LaManyNested_30) { RunManyNestedLoops_i(30); }
+TEST(LaManyNested_31) { RunManyNestedLoops_i(31); }
+TEST(LaManyNested_32) { RunManyNestedLoops_i(32); }
+TEST(LaManyNested_33) { RunManyNestedLoops_i(33); }
+TEST(LaManyNested_34) { RunManyNestedLoops_i(34); }
+TEST(LaManyNested_62) { RunManyNestedLoops_i(62); }
+TEST(LaManyNested_63) { RunManyNestedLoops_i(63); }
+TEST(LaManyNested_64) { RunManyNestedLoops_i(64); }
+
+
+TEST(LaPhiTangle) { LoopFinderTester t; }
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/test/cctest/compiler/test-loop-assignment-analysis.cc b/test/cctest/compiler/test-loop-assignment-analysis.cc
index aabd95b..69f5e15 100644
--- a/test/cctest/compiler/test-loop-assignment-analysis.cc
+++ b/test/cctest/compiler/test-loop-assignment-analysis.cc
@@ -2,14 +2,15 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "src/ast/scopes.h"
 #include "src/compiler/ast-loop-assignment-analyzer.h"
-#include "src/parser.h"
-#include "src/rewriter.h"
-#include "src/scopes.h"
+#include "src/parsing/parser.h"
+#include "src/parsing/rewriter.h"
 #include "test/cctest/cctest.h"
 
-using namespace v8::internal;
-using namespace v8::internal::compiler;
+namespace v8 {
+namespace internal {
+namespace compiler {
 
 namespace {
 const int kBufferSize = 1024;
@@ -29,28 +30,29 @@
 
   void CheckLoopAssignedCount(int expected, const char* var_name) {
     // TODO(titzer): don't scope analyze every single time.
-    CompilationInfo info(function, main_zone());
+    ParseInfo parse_info(main_zone(), function);
+    CompilationInfo info(&parse_info);
 
-    CHECK(Parser::Parse(&info));
-    CHECK(Rewriter::Rewrite(&info));
-    CHECK(Scope::Analyze(&info));
+    CHECK(Parser::ParseStatic(&parse_info));
+    CHECK(Rewriter::Rewrite(&parse_info));
+    CHECK(Scope::Analyze(&parse_info));
 
-    Scope* scope = info.function()->scope();
-    AstValueFactory* factory = info.ast_value_factory();
-    CHECK_NE(NULL, scope);
+    Scope* scope = info.literal()->scope();
+    AstValueFactory* factory = parse_info.ast_value_factory();
+    CHECK(scope);
 
     if (result == NULL) {
       AstLoopAssignmentAnalyzer analyzer(main_zone(), &info);
       result = analyzer.Analyze();
-      CHECK_NE(NULL, result);
+      CHECK(result);
     }
 
     const i::AstRawString* name = factory->GetOneByteString(var_name);
 
     i::Variable* var = scope->Lookup(name);
-    CHECK_NE(NULL, var);
+    CHECK(var);
 
-    if (var->location() == Variable::UNALLOCATED) {
+    if (var->location() == VariableLocation::UNALLOCATED) {
       CHECK_EQ(0, expected);
     } else {
       CHECK(var->IsStackAllocated());
@@ -58,7 +60,7 @@
     }
   }
 };
-}
+}  // namespace
 
 
 TEST(SimpleLoop1) {
@@ -292,3 +294,7 @@
   f.CheckLoopAssignedCount(5, "z");
   f.CheckLoopAssignedCount(0, "w");
 }
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/test/cctest/compiler/test-machine-operator-reducer.cc b/test/cctest/compiler/test-machine-operator-reducer.cc
index 648e1b9..86888e9 100644
--- a/test/cctest/compiler/test-machine-operator-reducer.cc
+++ b/test/cctest/compiler/test-machine-operator-reducer.cc
@@ -2,19 +2,18 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "test/cctest/cctest.h"
-
 #include "src/base/utils/random-number-generator.h"
 #include "src/codegen.h"
-#include "src/compiler/graph-inl.h"
 #include "src/compiler/js-graph.h"
 #include "src/compiler/machine-operator-reducer.h"
 #include "src/compiler/operator-properties.h"
 #include "src/compiler/typer.h"
+#include "test/cctest/cctest.h"
 #include "test/cctest/compiler/value-helper.h"
 
-using namespace v8::internal;
-using namespace v8::internal::compiler;
+namespace v8 {
+namespace internal {
+namespace compiler {
 
 template <typename T>
 const Operator* NewConstantOperator(CommonOperatorBuilder* common,
@@ -57,12 +56,12 @@
       : isolate(main_isolate()),
         binop(NULL),
         unop(NULL),
-        machine(main_zone(), kMachPtr, flags),
+        machine(main_zone(), MachineType::PointerRepresentation(), flags),
         common(main_zone()),
         graph(main_zone()),
         javascript(main_zone()),
-        typer(&graph, MaybeHandle<Context>()),
-        jsgraph(&graph, &common, &javascript, &machine),
+        typer(isolate, &graph),
+        jsgraph(isolate, &graph, &common, &javascript, nullptr, &machine),
         maxuint32(Constant<int32_t>(kMaxUInt32)) {
     Node* s = graph.NewNode(common.Start(num_parameters));
     graph.SetStart(s);
@@ -100,7 +99,7 @@
   // the {expect} value.
   template <typename T>
   void CheckFoldBinop(volatile T expect, Node* a, Node* b) {
-    CHECK_NE(NULL, binop);
+    CHECK(binop);
     Node* n = CreateBinopNode(a, b);
     MachineOperatorReducer reducer(&jsgraph);
     Reduction reduction = reducer.Reduce(n);
@@ -112,7 +111,7 @@
   // Check that the reduction of this binop applied to {a} and {b} yields
   // the {expect} node.
   void CheckBinop(Node* expect, Node* a, Node* b) {
-    CHECK_NE(NULL, binop);
+    CHECK(binop);
     Node* n = CreateBinopNode(a, b);
     MachineOperatorReducer reducer(&jsgraph);
     Reduction reduction = reducer.Reduce(n);
@@ -124,7 +123,7 @@
   // this binop applied to {left_expect} and {right_expect}.
   void CheckFoldBinop(Node* left_expect, Node* right_expect, Node* left,
                       Node* right) {
-    CHECK_NE(NULL, binop);
+    CHECK(binop);
     Node* n = CreateBinopNode(left, right);
     MachineOperatorReducer reducer(&jsgraph);
     Reduction reduction = reducer.Reduce(n);
@@ -139,7 +138,7 @@
   template <typename T>
   void CheckFoldBinop(volatile T left_expect, const Operator* op_expect,
                       Node* right_expect, Node* left, Node* right) {
-    CHECK_NE(NULL, binop);
+    CHECK(binop);
     Node* n = CreateBinopNode(left, right);
     MachineOperatorReducer reducer(&jsgraph);
     Reduction r = reducer.Reduce(n);
@@ -154,7 +153,7 @@
   template <typename T>
   void CheckFoldBinop(Node* left_expect, const Operator* op_expect,
                       volatile T right_expect, Node* left, Node* right) {
-    CHECK_NE(NULL, binop);
+    CHECK(binop);
     Node* n = CreateBinopNode(left, right);
     MachineOperatorReducer reducer(&jsgraph);
     Reduction r = reducer.Reduce(n);
@@ -360,7 +359,7 @@
 
 
 static void CheckJsShift(ReducerTester* R) {
-  DCHECK(R->machine.Word32ShiftIsSafe());
+  CHECK(R->machine.Word32ShiftIsSafe());
 
   Node* x = R->Parameter(0);
   Node* y = R->Parameter(1);
@@ -704,7 +703,8 @@
 
   Node* base = R.Constant<int32_t>(11);
   Node* index = R.Constant<int32_t>(4);
-  Node* load = R.graph.NewNode(R.machine.Load(kMachInt32), base, index);
+  Node* load = R.graph.NewNode(R.machine.Load(MachineType::Int32()), base,
+                               index, R.graph.start(), R.graph.start());
 
   {
     MachineOperatorReducer reducer(&R.jsgraph);
@@ -713,9 +713,10 @@
   }
 
   {
-    Node* store = R.graph.NewNode(
-        R.machine.Store(StoreRepresentation(kMachInt32, kNoWriteBarrier)), base,
-        index, load);
+    Node* store =
+        R.graph.NewNode(R.machine.Store(StoreRepresentation(
+                            MachineRepresentation::kWord32, kNoWriteBarrier)),
+                        base, index, load, load, R.graph.start());
     MachineOperatorReducer reducer(&R.jsgraph);
     Reduction reduction = reducer.Reduce(store);
     CHECK(!reduction.Changed());  // stores should not be reduced.
@@ -723,133 +724,6 @@
 }
 
 
-static void CheckNans(ReducerTester* R) {
-  Node* x = R->Parameter();
-  std::vector<double> nans = ValueHelper::nan_vector();
-  for (std::vector<double>::const_iterator pl = nans.begin(); pl != nans.end();
-       ++pl) {
-    for (std::vector<double>::const_iterator pr = nans.begin();
-         pr != nans.end(); ++pr) {
-      Node* nan1 = R->Constant<double>(*pl);
-      Node* nan2 = R->Constant<double>(*pr);
-      R->CheckBinop(nan1, x, nan1);     // x op NaN => NaN
-      R->CheckBinop(nan1, nan1, x);     // NaN op x => NaN
-      R->CheckBinop(nan1, nan2, nan1);  // NaN op NaN => NaN
-    }
-  }
-}
-
-
-TEST(ReduceFloat64Add) {
-  ReducerTester R;
-  R.binop = R.machine.Float64Add();
-
-  FOR_FLOAT64_INPUTS(pl) {
-    FOR_FLOAT64_INPUTS(pr) {
-      double x = *pl, y = *pr;
-      R.CheckFoldBinop<double>(x + y, x, y);
-    }
-  }
-
-  FOR_FLOAT64_INPUTS(i) {
-    Double tmp(*i);
-    if (!tmp.IsSpecial() || tmp.IsInfinite()) {
-      // Don't check NaNs as they are reduced more.
-      R.CheckPutConstantOnRight(*i);
-    }
-  }
-
-  CheckNans(&R);
-}
-
-
-TEST(ReduceFloat64Sub) {
-  ReducerTester R;
-  R.binop = R.machine.Float64Sub();
-
-  FOR_FLOAT64_INPUTS(pl) {
-    FOR_FLOAT64_INPUTS(pr) {
-      double x = *pl, y = *pr;
-      R.CheckFoldBinop<double>(x - y, x, y);
-    }
-  }
-
-  Node* zero = R.Constant<double>(0.0);
-  Node* x = R.Parameter();
-
-  R.CheckBinop(x, x, zero);  // x - 0.0 => x
-
-  CheckNans(&R);
-}
-
-
-TEST(ReduceFloat64Mul) {
-  ReducerTester R;
-  R.binop = R.machine.Float64Mul();
-
-  FOR_FLOAT64_INPUTS(pl) {
-    FOR_FLOAT64_INPUTS(pr) {
-      double x = *pl, y = *pr;
-      R.CheckFoldBinop<double>(x * y, x, y);
-    }
-  }
-
-  double inf = V8_INFINITY;
-  R.CheckPutConstantOnRight(-inf);
-  R.CheckPutConstantOnRight(-0.1);
-  R.CheckPutConstantOnRight(0.1);
-  R.CheckPutConstantOnRight(inf);
-
-  Node* x = R.Parameter();
-  Node* one = R.Constant<double>(1.0);
-
-  R.CheckBinop(x, x, one);  // x * 1.0 => x
-  R.CheckBinop(x, one, x);  // 1.0 * x => x
-
-  CheckNans(&R);
-}
-
-
-TEST(ReduceFloat64Div) {
-  ReducerTester R;
-  R.binop = R.machine.Float64Div();
-
-  FOR_FLOAT64_INPUTS(pl) {
-    FOR_FLOAT64_INPUTS(pr) {
-      double x = *pl, y = *pr;
-      R.CheckFoldBinop<double>(x / y, x, y);
-    }
-  }
-
-  Node* x = R.Parameter();
-  Node* one = R.Constant<double>(1.0);
-
-  R.CheckBinop(x, x, one);  // x / 1.0 => x
-
-  CheckNans(&R);
-}
-
-
-TEST(ReduceFloat64Mod) {
-  ReducerTester R;
-  R.binop = R.machine.Float64Mod();
-
-  FOR_FLOAT64_INPUTS(pl) {
-    FOR_FLOAT64_INPUTS(pr) {
-      double x = *pl, y = *pr;
-      R.CheckFoldBinop<double>(modulo(x, y), x, y);
-    }
-  }
-
-  Node* x = R.Parameter();
-  Node* zero = R.Constant<double>(0.0);
-
-  R.CheckFoldBinop<double>(v8::base::OS::nan_value(), x, zero);
-
-  CheckNans(&R);
-}
-
-
 // TODO(titzer): test MachineOperatorReducer for Word64And
 // TODO(titzer): test MachineOperatorReducer for Word64Or
 // TODO(titzer): test MachineOperatorReducer for Word64Xor
@@ -870,3 +744,12 @@
 // TODO(titzer): test MachineOperatorReducer for ChangeInt32ToFloat64
 // TODO(titzer): test MachineOperatorReducer for ChangeFloat64ToInt32
 // TODO(titzer): test MachineOperatorReducer for Float64Compare
+// TODO(titzer): test MachineOperatorReducer for Float64Add
+// TODO(titzer): test MachineOperatorReducer for Float64Sub
+// TODO(titzer): test MachineOperatorReducer for Float64Mul
+// TODO(titzer): test MachineOperatorReducer for Float64Div
+// TODO(titzer): test MachineOperatorReducer for Float64Mod
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/test/cctest/compiler/test-multiple-return.cc b/test/cctest/compiler/test-multiple-return.cc
new file mode 100644
index 0000000..7c08238
--- /dev/null
+++ b/test/cctest/compiler/test-multiple-return.cc
@@ -0,0 +1,118 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <cmath>
+#include <functional>
+#include <limits>
+
+#include "src/assembler.h"
+#include "src/base/bits.h"
+#include "src/base/utils/random-number-generator.h"
+#include "src/codegen.h"
+#include "src/compiler.h"
+#include "src/compiler/linkage.h"
+#include "src/macro-assembler.h"
+#include "test/cctest/cctest.h"
+#include "test/cctest/compiler/codegen-tester.h"
+#include "test/cctest/compiler/value-helper.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+namespace {
+
+CallDescriptor* GetCallDescriptor(Zone* zone, int return_count,
+                                  int param_count) {
+  MachineSignature::Builder msig(zone, return_count, param_count);
+  LocationSignature::Builder locations(zone, return_count, param_count);
+  const RegisterConfiguration* config =
+      RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN);
+
+  // Add return location(s).
+  CHECK(return_count <= config->num_allocatable_general_registers());
+  for (int i = 0; i < return_count; i++) {
+    msig.AddReturn(MachineType::Int32());
+    locations.AddReturn(
+        LinkageLocation::ForRegister(config->allocatable_general_codes()[i]));
+  }
+
+  // Add register and/or stack parameter(s).
+  CHECK(param_count <= config->num_allocatable_general_registers());
+  for (int i = 0; i < param_count; i++) {
+    msig.AddParam(MachineType::Int32());
+    locations.AddParam(
+        LinkageLocation::ForRegister(config->allocatable_general_codes()[i]));
+  }
+
+  const RegList kCalleeSaveRegisters = 0;
+  const RegList kCalleeSaveFPRegisters = 0;
+
+  // The target for WASM calls is always a code object.
+  MachineType target_type = MachineType::AnyTagged();
+  LinkageLocation target_loc = LinkageLocation::ForAnyRegister();
+  return new (zone) CallDescriptor(       // --
+      CallDescriptor::kCallCodeObject,    // kind
+      target_type,                        // target MachineType
+      target_loc,                         // target location
+      msig.Build(),                       // machine_sig
+      locations.Build(),                  // location_sig
+      0,                                  // js_parameter_count
+      compiler::Operator::kNoProperties,  // properties
+      kCalleeSaveRegisters,               // callee-saved registers
+      kCalleeSaveFPRegisters,             // callee-saved fp regs
+      CallDescriptor::kNoFlags,           // flags
+      "c-call");
+}
+}  // namespace
+
+
+TEST(ReturnThreeValues) {
+  Zone zone;
+  CallDescriptor* desc = GetCallDescriptor(&zone, 3, 2);
+  HandleAndZoneScope handles;
+  RawMachineAssembler m(handles.main_isolate(),
+                        new (handles.main_zone()) Graph(handles.main_zone()),
+                        desc, MachineType::PointerRepresentation(),
+                        InstructionSelector::SupportedMachineOperatorFlags());
+
+  Node* p0 = m.Parameter(0);
+  Node* p1 = m.Parameter(1);
+  Node* add = m.Int32Add(p0, p1);
+  Node* sub = m.Int32Sub(p0, p1);
+  Node* mul = m.Int32Mul(p0, p1);
+  m.Return(add, sub, mul);
+
+  CompilationInfo info("testing", handles.main_isolate(), handles.main_zone());
+  Handle<Code> code =
+      Pipeline::GenerateCodeForTesting(&info, desc, m.graph(), m.Export());
+#ifdef ENABLE_DISASSEMBLER
+  if (FLAG_print_code) {
+    OFStream os(stdout);
+    code->Disassemble("three_value", os);
+  }
+#endif
+
+  RawMachineAssemblerTester<int32_t> mt;
+  Node* a = mt.Int32Constant(123);
+  Node* b = mt.Int32Constant(456);
+  Node* ret3 = mt.AddNode(mt.common()->Call(desc), mt.HeapConstant(code), a, b);
+  Node* x = mt.AddNode(mt.common()->Projection(0), ret3);
+  Node* y = mt.AddNode(mt.common()->Projection(1), ret3);
+  Node* z = mt.AddNode(mt.common()->Projection(2), ret3);
+  Node* ret = mt.Int32Add(mt.Int32Add(x, y), z);
+  mt.Return(ret);
+#ifdef ENABLE_DISASSEMBLER
+  Handle<Code> code2 = mt.GetCode();
+  if (FLAG_print_code) {
+    OFStream os(stdout);
+    code2->Disassemble("three_value_call", os);
+  }
+#endif
+  CHECK_EQ((123 + 456) + (123 - 456) + (123 * 456), mt.Call());
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/test/cctest/compiler/test-node-algorithm.cc b/test/cctest/compiler/test-node-algorithm.cc
deleted file mode 100644
index 842d182..0000000
--- a/test/cctest/compiler/test-node-algorithm.cc
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright 2013 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <vector>
-
-#include "src/v8.h"
-
-#include "graph-tester.h"
-#include "src/compiler/common-operator.h"
-#include "src/compiler/graph.h"
-#include "src/compiler/graph-inl.h"
-#include "src/compiler/graph-visualizer.h"
-#include "src/compiler/node.h"
-#include "src/compiler/operator.h"
-
-using namespace v8::internal;
-using namespace v8::internal::compiler;
-
-static Operator dummy_operator(IrOpcode::kParameter, Operator::kNoWrite,
-                               "dummy", 0, 0, 0, 1, 0, 0);
-
-class PreNodeVisitor : public NullNodeVisitor {
- public:
-  void Pre(Node* node) {
-    printf("NODE ID: %d\n", node->id());
-    nodes_.push_back(node);
-  }
-  std::vector<Node*> nodes_;
-};
-
-
-class PostNodeVisitor : public NullNodeVisitor {
- public:
-  void Post(Node* node) {
-    printf("NODE ID: %d\n", node->id());
-    nodes_.push_back(node);
-  }
-  std::vector<Node*> nodes_;
-};
-
-
-TEST(TestInputNodePreOrderVisitSimple) {
-  GraphWithStartNodeTester graph;
-  Node* n2 = graph.NewNode(&dummy_operator, graph.start());
-  Node* n3 = graph.NewNode(&dummy_operator, n2);
-  Node* n4 = graph.NewNode(&dummy_operator, n2, n3);
-  Node* n5 = graph.NewNode(&dummy_operator, n4, n2);
-  graph.SetEnd(n5);
-
-  PreNodeVisitor node_visitor;
-  graph.VisitNodeInputsFromEnd(&node_visitor);
-  CHECK_EQ(5, static_cast<int>(node_visitor.nodes_.size()));
-  CHECK(n5->id() == node_visitor.nodes_[0]->id());
-  CHECK(n4->id() == node_visitor.nodes_[1]->id());
-  CHECK(n2->id() == node_visitor.nodes_[2]->id());
-  CHECK(graph.start()->id() == node_visitor.nodes_[3]->id());
-  CHECK(n3->id() == node_visitor.nodes_[4]->id());
-}
-
-
-TEST(TestPrintNodeGraphToNodeGraphviz) {
-  GraphWithStartNodeTester graph;
-  Node* n2 = graph.NewNode(&dummy_operator, graph.start());
-  Node* n3 = graph.NewNode(&dummy_operator, graph.start());
-  Node* n4 = graph.NewNode(&dummy_operator, n2);
-  Node* n5 = graph.NewNode(&dummy_operator, n2);
-  Node* n6 = graph.NewNode(&dummy_operator, n3);
-  Node* n7 = graph.NewNode(&dummy_operator, n3);
-  Node* n8 = graph.NewNode(&dummy_operator, n5);
-  Node* n9 = graph.NewNode(&dummy_operator, n5);
-  Node* n10 = graph.NewNode(&dummy_operator, n9);
-  Node* n11 = graph.NewNode(&dummy_operator, n9);
-  Node* end_dependencies[6] = {n4, n8, n10, n11, n6, n7};
-  Node* n12 = graph.NewNode(&dummy_operator, 6, end_dependencies);
-  graph.SetEnd(n12);
-
-  OFStream os(stdout);
-  os << AsDOT(graph);
-}
diff --git a/test/cctest/compiler/test-node-cache.cc b/test/cctest/compiler/test-node-cache.cc
deleted file mode 100644
index a48adb9..0000000
--- a/test/cctest/compiler/test-node-cache.cc
+++ /dev/null
@@ -1,175 +0,0 @@
-// Copyright 2014 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "src/v8.h"
-
-#include "graph-tester.h"
-#include "src/compiler/common-operator.h"
-#include "src/compiler/node-cache.h"
-
-using namespace v8::internal;
-using namespace v8::internal::compiler;
-
-TEST(Int32Constant_back_to_back) {
-  GraphTester graph;
-  Int32NodeCache cache;
-
-  for (int i = -2000000000; i < 2000000000; i += 3315177) {
-    Node** pos = cache.Find(graph.zone(), i);
-    CHECK_NE(NULL, pos);
-    for (int j = 0; j < 3; j++) {
-      Node** npos = cache.Find(graph.zone(), i);
-      CHECK_EQ(pos, npos);
-    }
-  }
-}
-
-
-TEST(Int32Constant_five) {
-  GraphTester graph;
-  Int32NodeCache cache;
-  CommonOperatorBuilder common(graph.zone());
-
-  int32_t constants[] = {static_cast<int32_t>(0x80000000), -77, 0, 1, -1};
-
-  Node* nodes[arraysize(constants)];
-
-  for (size_t i = 0; i < arraysize(constants); i++) {
-    int32_t k = constants[i];
-    Node* node = graph.NewNode(common.Int32Constant(k));
-    *cache.Find(graph.zone(), k) = nodes[i] = node;
-  }
-
-  for (size_t i = 0; i < arraysize(constants); i++) {
-    int32_t k = constants[i];
-    CHECK_EQ(nodes[i], *cache.Find(graph.zone(), k));
-  }
-}
-
-
-TEST(Int32Constant_hits) {
-  GraphTester graph;
-  Int32NodeCache cache;
-  const int32_t kSize = 1500;
-  Node** nodes = graph.zone()->NewArray<Node*>(kSize);
-  CommonOperatorBuilder common(graph.zone());
-
-  for (int i = 0; i < kSize; i++) {
-    int32_t v = i * -55;
-    nodes[i] = graph.NewNode(common.Int32Constant(v));
-    *cache.Find(graph.zone(), v) = nodes[i];
-  }
-
-  int hits = 0;
-  for (int i = 0; i < kSize; i++) {
-    int32_t v = i * -55;
-    Node** pos = cache.Find(graph.zone(), v);
-    if (*pos != NULL) {
-      CHECK_EQ(nodes[i], *pos);
-      hits++;
-    }
-  }
-  CHECK_LT(4, hits);
-}
-
-
-TEST(Int64Constant_back_to_back) {
-  GraphTester graph;
-  Int64NodeCache cache;
-
-  for (int64_t i = -2000000000; i < 2000000000; i += 3315177) {
-    Node** pos = cache.Find(graph.zone(), i);
-    CHECK_NE(NULL, pos);
-    for (int j = 0; j < 3; j++) {
-      Node** npos = cache.Find(graph.zone(), i);
-      CHECK_EQ(pos, npos);
-    }
-  }
-}
-
-
-TEST(Int64Constant_hits) {
-  GraphTester graph;
-  Int64NodeCache cache;
-  const int32_t kSize = 1500;
-  Node** nodes = graph.zone()->NewArray<Node*>(kSize);
-  CommonOperatorBuilder common(graph.zone());
-
-  for (int i = 0; i < kSize; i++) {
-    int64_t v = static_cast<int64_t>(i) * static_cast<int64_t>(5003001);
-    nodes[i] = graph.NewNode(common.Int32Constant(i));
-    *cache.Find(graph.zone(), v) = nodes[i];
-  }
-
-  int hits = 0;
-  for (int i = 0; i < kSize; i++) {
-    int64_t v = static_cast<int64_t>(i) * static_cast<int64_t>(5003001);
-    Node** pos = cache.Find(graph.zone(), v);
-    if (*pos != NULL) {
-      CHECK_EQ(nodes[i], *pos);
-      hits++;
-    }
-  }
-  CHECK_LT(4, hits);
-}
-
-
-static bool Contains(NodeVector* nodes, Node* n) {
-  for (size_t i = 0; i < nodes->size(); i++) {
-    if (nodes->at(i) == n) return true;
-  }
-  return false;
-}
-
-
-TEST(NodeCache_GetCachedNodes_int32) {
-  GraphTester graph;
-  Int32NodeCache cache;
-  CommonOperatorBuilder common(graph.zone());
-
-  int32_t constants[] = {0, 311, 12,  13,  14,  555, -555, -44, -33, -22, -11,
-                         0, 311, 311, 412, 412, 11,  11,   -33, -33, -22, -11};
-
-  for (size_t i = 0; i < arraysize(constants); i++) {
-    int32_t k = constants[i];
-    Node** pos = cache.Find(graph.zone(), k);
-    if (*pos != NULL) {
-      NodeVector nodes(graph.zone());
-      cache.GetCachedNodes(&nodes);
-      CHECK(Contains(&nodes, *pos));
-    } else {
-      NodeVector nodes(graph.zone());
-      Node* n = graph.NewNode(common.Int32Constant(k));
-      *pos = n;
-      cache.GetCachedNodes(&nodes);
-      CHECK(Contains(&nodes, n));
-    }
-  }
-}
-
-
-TEST(NodeCache_GetCachedNodes_int64) {
-  GraphTester graph;
-  Int64NodeCache cache;
-  CommonOperatorBuilder common(graph.zone());
-
-  int64_t constants[] = {0, 311, 12,  13,  14,  555, -555, -44, -33, -22, -11,
-                         0, 311, 311, 412, 412, 11,  11,   -33, -33, -22, -11};
-
-  for (size_t i = 0; i < arraysize(constants); i++) {
-    int64_t k = constants[i];
-    Node** pos = cache.Find(graph.zone(), k);
-    if (*pos != NULL) {
-      NodeVector nodes(graph.zone());
-      cache.GetCachedNodes(&nodes);
-      CHECK(Contains(&nodes, *pos));
-    } else {
-      NodeVector nodes(graph.zone());
-      Node* n = graph.NewNode(common.Int64Constant(k));
-      *pos = n;
-      cache.GetCachedNodes(&nodes);
-      CHECK(Contains(&nodes, n));
-    }
-  }
-}
diff --git a/test/cctest/compiler/test-node.cc b/test/cctest/compiler/test-node.cc
index eafabd3..de1c2c0 100644
--- a/test/cctest/compiler/test-node.cc
+++ b/test/cctest/compiler/test-node.cc
@@ -4,242 +4,233 @@
 
 #include <functional>
 
-#include "src/v8.h"
-
-#include "graph-tester.h"
+#include "src/compiler/graph.h"
 #include "src/compiler/node.h"
 #include "src/compiler/operator.h"
+#include "test/cctest/cctest.h"
 
-using namespace v8::internal;
-using namespace v8::internal::compiler;
+namespace v8 {
+namespace internal {
+namespace compiler {
 
-static Operator dummy_operator(IrOpcode::kParameter, Operator::kNoWrite,
-                               "dummy", 0, 0, 0, 1, 0, 0);
+#define NONE reinterpret_cast<Node*>(1)
 
-TEST(NodeAllocation) {
-  GraphTester graph;
-  Node* n1 = graph.NewNode(&dummy_operator);
-  Node* n2 = graph.NewNode(&dummy_operator);
-  CHECK(n2->id() != n1->id());
-}
+static Operator dummy_operator0(IrOpcode::kParameter, Operator::kNoWrite,
+                                "dummy", 0, 0, 0, 1, 0, 0);
+static Operator dummy_operator1(IrOpcode::kParameter, Operator::kNoWrite,
+                                "dummy", 1, 0, 0, 1, 0, 0);
+static Operator dummy_operator2(IrOpcode::kParameter, Operator::kNoWrite,
+                                "dummy", 2, 0, 0, 1, 0, 0);
+static Operator dummy_operator3(IrOpcode::kParameter, Operator::kNoWrite,
+                                "dummy", 3, 0, 0, 1, 0, 0);
+
+#define CHECK_USES(node, ...)                                          \
+  do {                                                                 \
+    Node* __array[] = {__VA_ARGS__};                                   \
+    int __size =                                                       \
+        __array[0] != NONE ? static_cast<int>(arraysize(__array)) : 0; \
+    CheckUseChain(node, __array, __size);                              \
+  } while (false)
 
 
-TEST(NodeWithOpcode) {
-  GraphTester graph;
-  Node* n1 = graph.NewNode(&dummy_operator);
-  Node* n2 = graph.NewNode(&dummy_operator);
-  CHECK(n1->op() == &dummy_operator);
-  CHECK(n2->op() == &dummy_operator);
-}
+namespace {
+
+typedef std::multiset<Node*, std::less<Node*>> NodeMSet;
 
 
-TEST(NodeInputs1) {
-  GraphTester graph;
-  Node* n0 = graph.NewNode(&dummy_operator);
-  Node* n2 = graph.NewNode(&dummy_operator, n0);
-  CHECK_EQ(1, n2->InputCount());
-  CHECK(n0 == n2->InputAt(0));
-}
-
-
-TEST(NodeInputs2) {
-  GraphTester graph;
-  Node* n0 = graph.NewNode(&dummy_operator);
-  Node* n1 = graph.NewNode(&dummy_operator);
-  Node* n2 = graph.NewNode(&dummy_operator, n0, n1);
-  CHECK_EQ(2, n2->InputCount());
-  CHECK(n0 == n2->InputAt(0));
-  CHECK(n1 == n2->InputAt(1));
-}
-
-
-TEST(NodeInputs3) {
-  GraphTester graph;
-  Node* n0 = graph.NewNode(&dummy_operator);
-  Node* n1 = graph.NewNode(&dummy_operator);
-  Node* n2 = graph.NewNode(&dummy_operator, n0, n1, n1);
-  CHECK_EQ(3, n2->InputCount());
-  CHECK(n0 == n2->InputAt(0));
-  CHECK(n1 == n2->InputAt(1));
-  CHECK(n1 == n2->InputAt(2));
-}
-
-
-TEST(NodeInputIteratorEmpty) {
-  GraphTester graph;
-  Node* n1 = graph.NewNode(&dummy_operator);
-  Node::Inputs::iterator i(n1->inputs().begin());
-  int input_count = 0;
-  for (; i != n1->inputs().end(); ++i) {
-    input_count++;
+void CheckUseChain(Node* node, Node** uses, int use_count) {
+  // Check ownership.
+  if (use_count == 1) CHECK(node->OwnedBy(uses[0]));
+  if (use_count > 1) {
+    for (int i = 0; i < use_count; i++) {
+      CHECK(!node->OwnedBy(uses[i]));
+    }
   }
-  CHECK_EQ(0, input_count);
-}
 
+  // Check the self-reported use count.
+  CHECK_EQ(use_count, node->UseCount());
 
-TEST(NodeInputIteratorOne) {
-  GraphTester graph;
-  Node* n0 = graph.NewNode(&dummy_operator);
-  Node* n1 = graph.NewNode(&dummy_operator, n0);
-  Node::Inputs::iterator i(n1->inputs().begin());
-  CHECK_EQ(1, n1->InputCount());
-  CHECK_EQ(n0, *i);
-  ++i;
-  CHECK(n1->inputs().end() == i);
-}
-
-
-TEST(NodeUseIteratorEmpty) {
-  GraphTester graph;
-  Node* n1 = graph.NewNode(&dummy_operator);
-  int use_count = 0;
-  for (Edge const edge : n1->use_edges()) {
-    USE(edge);
-    use_count++;
+  // Build the expectation set.
+  NodeMSet expect_set;
+  for (int i = 0; i < use_count; i++) {
+    expect_set.insert(uses[i]);
   }
-  CHECK_EQ(0, use_count);
+
+  {
+    // Check that iterating over the uses gives the right counts.
+    NodeMSet use_set;
+    for (auto use : node->uses()) {
+      use_set.insert(use);
+    }
+    CHECK(expect_set == use_set);
+  }
+
+  {
+    // Check that iterating over the use edges gives the right counts,
+    // input indices, from(), and to() pointers.
+    NodeMSet use_set;
+    for (auto edge : node->use_edges()) {
+      CHECK_EQ(node, edge.to());
+      CHECK_EQ(node, edge.from()->InputAt(edge.index()));
+      use_set.insert(edge.from());
+    }
+    CHECK(expect_set == use_set);
+  }
+
+  {
+    // Check the use nodes actually have the node as inputs.
+    for (Node* use : node->uses()) {
+      size_t count = 0;
+      for (Node* input : use->inputs()) {
+        if (input == node) count++;
+      }
+      CHECK_EQ(count, expect_set.count(use));
+    }
+  }
 }
 
 
-TEST(NodeUseIteratorOne) {
-  GraphTester graph;
-  Node* n0 = graph.NewNode(&dummy_operator);
-  Node* n1 = graph.NewNode(&dummy_operator, n0);
-  Node::Uses::iterator i(n0->uses().begin());
-  CHECK_EQ(n1, *i);
-  ++i;
-  CHECK(n0->uses().end() == i);
+void CheckInputs(Node* node, Node** inputs, int input_count) {
+  CHECK_EQ(input_count, node->InputCount());
+  // Check InputAt().
+  for (int i = 0; i < static_cast<int>(input_count); i++) {
+    CHECK_EQ(inputs[i], node->InputAt(i));
+  }
+
+  // Check input iterator.
+  int index = 0;
+  for (Node* input : node->inputs()) {
+    CHECK_EQ(inputs[index], input);
+    index++;
+  }
+
+  // Check use lists of inputs.
+  for (int i = 0; i < static_cast<int>(input_count); i++) {
+    Node* input = inputs[i];
+    if (!input) continue;  // skip null inputs
+    bool found = false;
+    // Check regular use list.
+    for (Node* use : input->uses()) {
+      if (use == node) {
+        found = true;
+        break;
+      }
+    }
+    CHECK(found);
+    int count = 0;
+    // Check use edge list.
+    for (auto edge : input->use_edges()) {
+      if (edge.from() == node && edge.to() == input && edge.index() == i) {
+        count++;
+      }
+    }
+    CHECK_EQ(1, count);
+  }
 }
 
+}  // namespace
 
-TEST(NodeUseIteratorReplaceNoUses) {
-  GraphTester graph;
-  Node* n0 = graph.NewNode(&dummy_operator);
-  Node* n1 = graph.NewNode(&dummy_operator);
-  Node* n2 = graph.NewNode(&dummy_operator);
-  Node* n3 = graph.NewNode(&dummy_operator, n2);
-  n0->ReplaceUses(n1);
-  CHECK(n0->uses().begin() == n0->uses().end());
-  n0->ReplaceUses(n2);
-  CHECK(n0->uses().begin() == n0->uses().end());
-  USE(n3);
-}
+
+#define CHECK_INPUTS(node, ...)                                        \
+  do {                                                                 \
+    Node* __array[] = {__VA_ARGS__};                                   \
+    int __size =                                                       \
+        __array[0] != NONE ? static_cast<int>(arraysize(__array)) : 0; \
+    CheckInputs(node, __array, __size);                                \
+  } while (false)
 
 
 TEST(NodeUseIteratorReplaceUses) {
-  GraphTester graph;
-  Node* n0 = graph.NewNode(&dummy_operator);
-  Node* n1 = graph.NewNode(&dummy_operator, n0);
-  Node* n2 = graph.NewNode(&dummy_operator, n0);
-  Node* n3 = graph.NewNode(&dummy_operator);
-  Node::Uses::iterator i1(n0->uses().begin());
-  CHECK_EQ(n1, *i1);
-  ++i1;
-  CHECK_EQ(n2, *i1);
+  Zone zone;
+  Graph graph(&zone);
+  Node* n0 = graph.NewNode(&dummy_operator0);
+  Node* n1 = graph.NewNode(&dummy_operator1, n0);
+  Node* n2 = graph.NewNode(&dummy_operator1, n0);
+  Node* n3 = graph.NewNode(&dummy_operator0);
+
+  CHECK_USES(n0, n1, n2);
+
+  CHECK_INPUTS(n1, n0);
+  CHECK_INPUTS(n2, n0);
+
   n0->ReplaceUses(n3);
-  Node::Uses::iterator i2(n3->uses().begin());
-  CHECK_EQ(n1, *i2);
-  ++i2;
-  CHECK_EQ(n2, *i2);
-  Node::Inputs::iterator i3(n1->inputs().begin());
-  CHECK_EQ(n3, *i3);
-  ++i3;
-  CHECK(n1->inputs().end() == i3);
-  Node::Inputs::iterator i4(n2->inputs().begin());
-  CHECK_EQ(n3, *i4);
-  ++i4;
-  CHECK(n2->inputs().end() == i4);
+
+  CHECK_USES(n0, NONE);
+  CHECK_USES(n1, NONE);
+  CHECK_USES(n2, NONE);
+  CHECK_USES(n3, n1, n2);
+
+  CHECK_INPUTS(n1, n3);
+  CHECK_INPUTS(n2, n3);
 }
 
 
 TEST(NodeUseIteratorReplaceUsesSelf) {
-  GraphTester graph;
-  Node* n0 = graph.NewNode(&dummy_operator);
-  Node* n1 = graph.NewNode(&dummy_operator, n0);
-  Node* n3 = graph.NewNode(&dummy_operator);
+  Zone zone;
+  Graph graph(&zone);
+  Node* n0 = graph.NewNode(&dummy_operator0);
+  Node* n1 = graph.NewNode(&dummy_operator1, n0);
+
+  CHECK_USES(n0, n1);
+  CHECK_USES(n1, NONE);
 
   n1->ReplaceInput(0, n1);  // Create self-reference.
 
-  Node::Uses::iterator i1(n1->uses().begin());
-  CHECK_EQ(n1, *i1);
+  CHECK_USES(n0, NONE);
+  CHECK_USES(n1, n1);
 
-  n1->ReplaceUses(n3);
+  Node* n2 = graph.NewNode(&dummy_operator0);
 
-  CHECK(n1->uses().begin() == n1->uses().end());
+  n1->ReplaceUses(n2);
 
-  Node::Uses::iterator i2(n3->uses().begin());
-  CHECK_EQ(n1, *i2);
-  ++i2;
-  CHECK(n1->uses().end() == i2);
+  CHECK_USES(n0, NONE);
+  CHECK_USES(n1, NONE);
+  CHECK_USES(n2, n1);
 }
 
 
 TEST(ReplaceInput) {
-  GraphTester graph;
-  Node* n0 = graph.NewNode(&dummy_operator);
-  Node* n1 = graph.NewNode(&dummy_operator);
-  Node* n2 = graph.NewNode(&dummy_operator);
-  Node* n3 = graph.NewNode(&dummy_operator, n0, n1, n2);
-  Node::Inputs::iterator i1(n3->inputs().begin());
-  CHECK(n0 == *i1);
-  CHECK_EQ(n0, n3->InputAt(0));
-  ++i1;
-  CHECK_EQ(n1, *i1);
-  CHECK_EQ(n1, n3->InputAt(1));
-  ++i1;
-  CHECK_EQ(n2, *i1);
-  CHECK_EQ(n2, n3->InputAt(2));
-  ++i1;
-  CHECK(i1 == n3->inputs().end());
+  Zone zone;
+  Graph graph(&zone);
+  Node* n0 = graph.NewNode(&dummy_operator0);
+  Node* n1 = graph.NewNode(&dummy_operator0);
+  Node* n2 = graph.NewNode(&dummy_operator0);
+  Node* n3 = graph.NewNode(&dummy_operator3, n0, n1, n2);
+  Node* n4 = graph.NewNode(&dummy_operator0);
 
-  Node::Uses::iterator i2(n1->uses().begin());
-  CHECK_EQ(n3, *i2);
-  ++i2;
-  CHECK(i2 == n1->uses().end());
+  CHECK_USES(n0, n3);
+  CHECK_USES(n1, n3);
+  CHECK_USES(n2, n3);
+  CHECK_USES(n3, NONE);
+  CHECK_USES(n4, NONE);
 
-  Node* n4 = graph.NewNode(&dummy_operator);
-  Node::Uses::iterator i3(n4->uses().begin());
-  CHECK(i3 == n4->uses().end());
+  CHECK_INPUTS(n3, n0, n1, n2);
 
   n3->ReplaceInput(1, n4);
 
-  Node::Uses::iterator i4(n1->uses().begin());
-  CHECK(i4 == n1->uses().end());
+  CHECK_USES(n1, NONE);
+  CHECK_USES(n4, n3);
 
-  Node::Uses::iterator i5(n4->uses().begin());
-  CHECK_EQ(n3, *i5);
-  ++i5;
-  CHECK(i5 == n4->uses().end());
-
-  Node::Inputs::iterator i6(n3->inputs().begin());
-  CHECK(n0 == *i6);
-  CHECK_EQ(n0, n3->InputAt(0));
-  ++i6;
-  CHECK_EQ(n4, *i6);
-  CHECK_EQ(n4, n3->InputAt(1));
-  ++i6;
-  CHECK_EQ(n2, *i6);
-  CHECK_EQ(n2, n3->InputAt(2));
-  ++i6;
-  CHECK(i6 == n3->inputs().end());
+  CHECK_INPUTS(n3, n0, n4, n2);
 }
 
 
 TEST(OwnedBy) {
-  GraphTester graph;
+  Zone zone;
+  Graph graph(&zone);
 
   {
-    Node* n0 = graph.NewNode(&dummy_operator);
-    Node* n1 = graph.NewNode(&dummy_operator);
+    Node* n0 = graph.NewNode(&dummy_operator0);
+    Node* n1 = graph.NewNode(&dummy_operator0);
 
     CHECK(!n0->OwnedBy(n1));
     CHECK(!n1->OwnedBy(n0));
 
-    Node* n2 = graph.NewNode(&dummy_operator, n0);
+    Node* n2 = graph.NewNode(&dummy_operator1, n0);
     CHECK(n0->OwnedBy(n2));
     CHECK(!n2->OwnedBy(n0));
 
-    Node* n3 = graph.NewNode(&dummy_operator, n0);
+    Node* n3 = graph.NewNode(&dummy_operator1, n0);
     CHECK(!n0->OwnedBy(n2));
     CHECK(!n0->OwnedBy(n3));
     CHECK(!n2->OwnedBy(n0));
@@ -247,11 +238,11 @@
   }
 
   {
-    Node* n0 = graph.NewNode(&dummy_operator);
-    Node* n1 = graph.NewNode(&dummy_operator, n0);
+    Node* n0 = graph.NewNode(&dummy_operator0);
+    Node* n1 = graph.NewNode(&dummy_operator1, n0);
     CHECK(n0->OwnedBy(n1));
     CHECK(!n1->OwnedBy(n0));
-    Node* n2 = graph.NewNode(&dummy_operator, n0);
+    Node* n2 = graph.NewNode(&dummy_operator1, n0);
     CHECK(!n0->OwnedBy(n1));
     CHECK(!n0->OwnedBy(n2));
     CHECK(!n1->OwnedBy(n0));
@@ -259,7 +250,7 @@
     CHECK(!n2->OwnedBy(n0));
     CHECK(!n2->OwnedBy(n1));
 
-    Node* n3 = graph.NewNode(&dummy_operator);
+    Node* n3 = graph.NewNode(&dummy_operator0);
     n2->ReplaceInput(0, n3);
 
     CHECK(n0->OwnedBy(n1));
@@ -275,276 +266,197 @@
 
 
 TEST(Uses) {
-  GraphTester graph;
+  Zone zone;
+  Graph graph(&zone);
 
-  Node* n0 = graph.NewNode(&dummy_operator);
-  Node* n1 = graph.NewNode(&dummy_operator, n0);
-  CHECK_EQ(1, n0->UseCount());
-  printf("A: %d vs %d\n", n0->UseAt(0)->id(), n1->id());
-  CHECK(n0->UseAt(0) == n1);
-  Node* n2 = graph.NewNode(&dummy_operator, n0);
-  CHECK_EQ(2, n0->UseCount());
-  printf("B: %d vs %d\n", n0->UseAt(1)->id(), n2->id());
-  CHECK(n0->UseAt(1) == n2);
-  Node* n3 = graph.NewNode(&dummy_operator, n0);
-  CHECK_EQ(3, n0->UseCount());
-  CHECK(n0->UseAt(2) == n3);
+  Node* n0 = graph.NewNode(&dummy_operator0);
+  Node* n1 = graph.NewNode(&dummy_operator1, n0);
+
+  CHECK_USES(n0, n1);
+  CHECK_USES(n1, NONE);
+
+  Node* n2 = graph.NewNode(&dummy_operator1, n0);
+
+  CHECK_USES(n0, n1, n2);
+  CHECK_USES(n2, NONE);
+
+  Node* n3 = graph.NewNode(&dummy_operator1, n0);
+
+  CHECK_USES(n0, n1, n2, n3);
+  CHECK_USES(n3, NONE);
 }
 
 
 TEST(Inputs) {
-  GraphTester graph;
+  Zone zone;
+  Graph graph(&zone);
 
-  Node* n0 = graph.NewNode(&dummy_operator);
-  Node* n1 = graph.NewNode(&dummy_operator, n0);
-  Node* n2 = graph.NewNode(&dummy_operator, n0);
-  Node* n3 = graph.NewNode(&dummy_operator, n0, n1, n2);
-  CHECK_EQ(3, n3->InputCount());
-  CHECK(n3->InputAt(0) == n0);
-  CHECK(n3->InputAt(1) == n1);
-  CHECK(n3->InputAt(2) == n2);
-  Node* n4 = graph.NewNode(&dummy_operator, n0, n1, n2);
-  n3->AppendInput(graph.zone(), n4);
-  CHECK_EQ(4, n3->InputCount());
-  CHECK(n3->InputAt(0) == n0);
-  CHECK(n3->InputAt(1) == n1);
-  CHECK(n3->InputAt(2) == n2);
-  CHECK(n3->InputAt(3) == n4);
-  Node* n5 = graph.NewNode(&dummy_operator, n4);
-  n3->AppendInput(graph.zone(), n4);
-  CHECK_EQ(5, n3->InputCount());
-  CHECK(n3->InputAt(0) == n0);
-  CHECK(n3->InputAt(1) == n1);
-  CHECK(n3->InputAt(2) == n2);
-  CHECK(n3->InputAt(3) == n4);
-  CHECK(n3->InputAt(4) == n4);
+  Node* n0 = graph.NewNode(&dummy_operator0);
+  Node* n1 = graph.NewNode(&dummy_operator1, n0);
+  Node* n2 = graph.NewNode(&dummy_operator1, n0);
+  Node* n3 = graph.NewNode(&dummy_operator3, n0, n1, n2);
 
-  // Make sure uses have been hooked op correctly.
-  Node::Uses uses(n4->uses());
-  Node::Uses::iterator current = uses.begin();
-  CHECK(current != uses.end());
-  CHECK(*current == n3);
-  ++current;
-  CHECK(current != uses.end());
-  CHECK(*current == n5);
-  ++current;
-  CHECK(current != uses.end());
-  CHECK(*current == n3);
-  ++current;
-  CHECK(current == uses.end());
+  CHECK_INPUTS(n3, n0, n1, n2);
+
+  Node* n4 = graph.NewNode(&dummy_operator3, n0, n1, n2);
+  n3->AppendInput(graph.zone(), n4);
+
+  CHECK_INPUTS(n3, n0, n1, n2, n4);
+  CHECK_USES(n4, n3);
+
+  n3->AppendInput(graph.zone(), n4);
+
+  CHECK_INPUTS(n3, n0, n1, n2, n4, n4);
+  CHECK_USES(n4, n3, n3);
+
+  Node* n5 = graph.NewNode(&dummy_operator1, n4);
+
+  CHECK_USES(n4, n3, n3, n5);
 }
 
 
 TEST(RemoveInput) {
-  GraphTester graph;
+  Zone zone;
+  Graph graph(&zone);
 
-  Node* n0 = graph.NewNode(&dummy_operator);
-  Node* n1 = graph.NewNode(&dummy_operator, n0);
-  Node* n2 = graph.NewNode(&dummy_operator, n0, n1);
+  Node* n0 = graph.NewNode(&dummy_operator0);
+  Node* n1 = graph.NewNode(&dummy_operator1, n0);
+  Node* n2 = graph.NewNode(&dummy_operator2, n0, n1);
+
+  CHECK_INPUTS(n0, NONE);
+  CHECK_INPUTS(n1, n0);
+  CHECK_INPUTS(n2, n0, n1);
+  CHECK_USES(n0, n1, n2);
 
   n1->RemoveInput(0);
-  CHECK_EQ(0, n1->InputCount());
-  CHECK_EQ(1, n0->UseCount());
+  CHECK_INPUTS(n1, NONE);
+  CHECK_USES(n0, n2);
 
   n2->RemoveInput(0);
-  CHECK_EQ(1, n2->InputCount());
-  CHECK_EQ(0, n0->UseCount());
-  CHECK_EQ(1, n1->UseCount());
+  CHECK_INPUTS(n2, n1);
+  CHECK_USES(n0, NONE);
+  CHECK_USES(n1, n2);
 
   n2->RemoveInput(0);
-  CHECK_EQ(0, n2->InputCount());
+  CHECK_INPUTS(n2, NONE);
+  CHECK_USES(n0, NONE);
+  CHECK_USES(n1, NONE);
+  CHECK_USES(n2, NONE);
 }
 
 
 TEST(AppendInputsAndIterator) {
-  GraphTester graph;
+  Zone zone;
+  Graph graph(&zone);
 
-  Node* n0 = graph.NewNode(&dummy_operator);
-  Node* n1 = graph.NewNode(&dummy_operator, n0);
-  Node* n2 = graph.NewNode(&dummy_operator, n0, n1);
+  Node* n0 = graph.NewNode(&dummy_operator0);
+  Node* n1 = graph.NewNode(&dummy_operator1, n0);
+  Node* n2 = graph.NewNode(&dummy_operator2, n0, n1);
 
-  Node::InputEdges inputs(n2->input_edges());
-  Node::InputEdges::iterator current = inputs.begin();
-  CHECK(current != inputs.end());
-  CHECK((*current).to() == n0);
-  ++current;
-  CHECK(current != inputs.end());
-  CHECK((*current).to() == n1);
-  ++current;
-  CHECK(current == inputs.end());
+  CHECK_INPUTS(n0, NONE);
+  CHECK_INPUTS(n1, n0);
+  CHECK_INPUTS(n2, n0, n1);
+  CHECK_USES(n0, n1, n2);
 
-  Node* n3 = graph.NewNode(&dummy_operator);
+  Node* n3 = graph.NewNode(&dummy_operator0);
+
   n2->AppendInput(graph.zone(), n3);
-  inputs = n2->input_edges();
-  current = inputs.begin();
-  CHECK(current != inputs.end());
-  CHECK((*current).to() == n0);
-  CHECK_EQ(0, (*current).index());
-  ++current;
-  CHECK(current != inputs.end());
-  CHECK((*current).to() == n1);
-  CHECK_EQ(1, (*current).index());
-  ++current;
-  CHECK(current != inputs.end());
-  CHECK((*current).to() == n3);
-  CHECK_EQ(2, (*current).index());
-  ++current;
-  CHECK(current == inputs.end());
+
+  CHECK_INPUTS(n2, n0, n1, n3);
+  CHECK_USES(n3, n2);
 }
 
 
 TEST(NullInputsSimple) {
-  GraphTester graph;
+  Zone zone;
+  Graph graph(&zone);
 
-  Node* n0 = graph.NewNode(&dummy_operator);
-  Node* n1 = graph.NewNode(&dummy_operator, n0);
-  Node* n2 = graph.NewNode(&dummy_operator, n0, n1);
-  CHECK_EQ(2, n2->InputCount());
+  Node* n0 = graph.NewNode(&dummy_operator0);
+  Node* n1 = graph.NewNode(&dummy_operator1, n0);
+  Node* n2 = graph.NewNode(&dummy_operator2, n0, n1);
 
-  CHECK(n0 == n2->InputAt(0));
-  CHECK(n1 == n2->InputAt(1));
-  CHECK_EQ(2, n0->UseCount());
-  n2->ReplaceInput(0, NULL);
-  CHECK(NULL == n2->InputAt(0));
-  CHECK(n1 == n2->InputAt(1));
-  CHECK_EQ(1, n0->UseCount());
+  CHECK_INPUTS(n0, NONE);
+  CHECK_INPUTS(n1, n0);
+  CHECK_INPUTS(n2, n0, n1);
+  CHECK_USES(n0, n1, n2);
+
+  n2->ReplaceInput(0, nullptr);
+
+  CHECK_INPUTS(n2, NULL, n1);
+
+  CHECK_USES(n0, n1);
+
+  n2->ReplaceInput(1, nullptr);
+
+  CHECK_INPUTS(n2, NULL, NULL);
+
+  CHECK_USES(n1, NONE);
 }
 
 
 TEST(NullInputsAppended) {
-  GraphTester graph;
+  Zone zone;
+  Graph graph(&zone);
 
-  Node* n0 = graph.NewNode(&dummy_operator);
-  Node* n1 = graph.NewNode(&dummy_operator, n0);
-  Node* n2 = graph.NewNode(&dummy_operator, n0);
-  Node* n3 = graph.NewNode(&dummy_operator, n0);
+  Node* n0 = graph.NewNode(&dummy_operator0);
+  Node* n1 = graph.NewNode(&dummy_operator1, n0);
+  Node* n2 = graph.NewNode(&dummy_operator1, n0);
+  Node* n3 = graph.NewNode(&dummy_operator1, n0);
   n3->AppendInput(graph.zone(), n1);
   n3->AppendInput(graph.zone(), n2);
-  CHECK_EQ(3, n3->InputCount());
 
-  CHECK(n0 == n3->InputAt(0));
-  CHECK(n1 == n3->InputAt(1));
-  CHECK(n2 == n3->InputAt(2));
-  CHECK_EQ(1, n1->UseCount());
+  CHECK_INPUTS(n3, n0, n1, n2);
+  CHECK_USES(n0, n1, n2, n3);
+  CHECK_USES(n1, n3);
+  CHECK_USES(n2, n3);
+
   n3->ReplaceInput(1, NULL);
-  CHECK(n0 == n3->InputAt(0));
-  CHECK(NULL == n3->InputAt(1));
-  CHECK(n2 == n3->InputAt(2));
-  CHECK_EQ(0, n1->UseCount());
+  CHECK_USES(n1, NONE);
+
+  CHECK_INPUTS(n3, n0, NULL, n2);
 }
 
 
 TEST(ReplaceUsesFromAppendedInputs) {
-  GraphTester graph;
+  Zone zone;
+  Graph graph(&zone);
 
-  Node* n0 = graph.NewNode(&dummy_operator);
-  Node* n1 = graph.NewNode(&dummy_operator, n0);
-  Node* n2 = graph.NewNode(&dummy_operator, n0);
-  Node* n3 = graph.NewNode(&dummy_operator);
+  Node* n0 = graph.NewNode(&dummy_operator0);
+  Node* n1 = graph.NewNode(&dummy_operator1, n0);
+  Node* n2 = graph.NewNode(&dummy_operator1, n0);
+  Node* n3 = graph.NewNode(&dummy_operator0);
+
+  CHECK_INPUTS(n2, n0);
+
   n2->AppendInput(graph.zone(), n1);
+  CHECK_INPUTS(n2, n0, n1);
+  CHECK_USES(n1, n2);
+
   n2->AppendInput(graph.zone(), n0);
-  CHECK_EQ(0, n3->UseCount());
-  CHECK_EQ(3, n0->UseCount());
+  CHECK_INPUTS(n2, n0, n1, n0);
+  CHECK_USES(n1, n2);
+  CHECK_USES(n0, n2, n1, n2);
+
   n0->ReplaceUses(n3);
-  CHECK_EQ(0, n0->UseCount());
-  CHECK_EQ(3, n3->UseCount());
 
-  Node::Uses uses(n3->uses());
-  Node::Uses::iterator current = uses.begin();
-  CHECK(current != uses.end());
-  CHECK(*current == n1);
-  ++current;
-  CHECK(current != uses.end());
-  CHECK(*current == n2);
-  ++current;
-  CHECK(current != uses.end());
-  CHECK(*current == n2);
-  ++current;
-  CHECK(current == uses.end());
-}
-
-
-template <bool result>
-struct FixedPredicate {
-  bool operator()(const Node* node) const { return result; }
-};
-
-
-TEST(ReplaceUsesIfWithFixedPredicate) {
-  GraphTester graph;
-
-  Node* n0 = graph.NewNode(&dummy_operator);
-  Node* n1 = graph.NewNode(&dummy_operator, n0);
-  Node* n2 = graph.NewNode(&dummy_operator, n0);
-  Node* n3 = graph.NewNode(&dummy_operator);
-
-  CHECK_EQ(0, n2->UseCount());
-  n2->ReplaceUsesIf(FixedPredicate<true>(), n1);
-  CHECK_EQ(0, n2->UseCount());
-  n2->ReplaceUsesIf(FixedPredicate<false>(), n1);
-  CHECK_EQ(0, n2->UseCount());
-
-  CHECK_EQ(0, n3->UseCount());
-  n3->ReplaceUsesIf(FixedPredicate<true>(), n1);
-  CHECK_EQ(0, n3->UseCount());
-  n3->ReplaceUsesIf(FixedPredicate<false>(), n1);
-  CHECK_EQ(0, n3->UseCount());
-
-  CHECK_EQ(2, n0->UseCount());
-  CHECK_EQ(0, n1->UseCount());
-  n0->ReplaceUsesIf(FixedPredicate<false>(), n1);
-  CHECK_EQ(2, n0->UseCount());
-  CHECK_EQ(0, n1->UseCount());
-  n0->ReplaceUsesIf(FixedPredicate<true>(), n1);
-  CHECK_EQ(0, n0->UseCount());
-  CHECK_EQ(2, n1->UseCount());
-
-  n1->AppendInput(graph.zone(), n1);
-  CHECK_EQ(3, n1->UseCount());
-  n1->AppendInput(graph.zone(), n3);
-  CHECK_EQ(1, n3->UseCount());
-  n3->ReplaceUsesIf(FixedPredicate<true>(), n1);
-  CHECK_EQ(4, n1->UseCount());
-  CHECK_EQ(0, n3->UseCount());
-  n1->ReplaceUsesIf(FixedPredicate<false>(), n3);
-  CHECK_EQ(4, n1->UseCount());
-  CHECK_EQ(0, n3->UseCount());
-}
-
-
-TEST(ReplaceUsesIfWithEqualTo) {
-  GraphTester graph;
-
-  Node* n0 = graph.NewNode(&dummy_operator);
-  Node* n1 = graph.NewNode(&dummy_operator, n0);
-  Node* n2 = graph.NewNode(&dummy_operator, n0, n1);
-
-  CHECK_EQ(0, n2->UseCount());
-  n2->ReplaceUsesIf(std::bind1st(std::equal_to<Node*>(), n1), n0);
-  CHECK_EQ(0, n2->UseCount());
-
-  CHECK_EQ(2, n0->UseCount());
-  CHECK_EQ(1, n1->UseCount());
-  n1->ReplaceUsesIf(std::bind1st(std::equal_to<Node*>(), n0), n0);
-  CHECK_EQ(2, n0->UseCount());
-  CHECK_EQ(1, n1->UseCount());
-  n0->ReplaceUsesIf(std::bind2nd(std::equal_to<Node*>(), n2), n1);
-  CHECK_EQ(1, n0->UseCount());
-  CHECK_EQ(2, n1->UseCount());
+  CHECK_USES(n0, NONE);
+  CHECK_INPUTS(n2, n3, n1, n3);
+  CHECK_USES(n3, n2, n1, n2);
 }
 
 
 TEST(ReplaceInputMultipleUses) {
-  GraphTester graph;
+  Zone zone;
+  Graph graph(&zone);
 
-  Node* n0 = graph.NewNode(&dummy_operator);
-  Node* n1 = graph.NewNode(&dummy_operator);
-  Node* n2 = graph.NewNode(&dummy_operator, n0);
+  Node* n0 = graph.NewNode(&dummy_operator0);
+  Node* n1 = graph.NewNode(&dummy_operator0);
+  Node* n2 = graph.NewNode(&dummy_operator1, n0);
   n2->ReplaceInput(0, n1);
   CHECK_EQ(0, n0->UseCount());
   CHECK_EQ(1, n1->UseCount());
 
-  Node* n3 = graph.NewNode(&dummy_operator, n0);
+  Node* n3 = graph.NewNode(&dummy_operator1, n0);
   n3->ReplaceInput(0, n1);
   CHECK_EQ(0, n0->UseCount());
   CHECK_EQ(2, n1->UseCount());
@@ -552,94 +464,92 @@
 
 
 TEST(TrimInputCountInline) {
-  GraphTester graph;
+  Zone zone;
+  Graph graph(&zone);
 
   {
-    Node* n0 = graph.NewNode(&dummy_operator);
-    Node* n1 = graph.NewNode(&dummy_operator, n0);
+    Node* n0 = graph.NewNode(&dummy_operator0);
+    Node* n1 = graph.NewNode(&dummy_operator1, n0);
     n1->TrimInputCount(1);
-    CHECK_EQ(1, n1->InputCount());
-    CHECK_EQ(n0, n1->InputAt(0));
-    CHECK_EQ(1, n0->UseCount());
+    CHECK_INPUTS(n1, n0);
+    CHECK_USES(n0, n1);
   }
 
   {
-    Node* n0 = graph.NewNode(&dummy_operator);
-    Node* n1 = graph.NewNode(&dummy_operator, n0);
+    Node* n0 = graph.NewNode(&dummy_operator0);
+    Node* n1 = graph.NewNode(&dummy_operator1, n0);
     n1->TrimInputCount(0);
-    CHECK_EQ(0, n1->InputCount());
-    CHECK_EQ(0, n0->UseCount());
+    CHECK_INPUTS(n1, NONE);
+    CHECK_USES(n0, NONE);
   }
 
   {
-    Node* n0 = graph.NewNode(&dummy_operator);
-    Node* n1 = graph.NewNode(&dummy_operator);
-    Node* n2 = graph.NewNode(&dummy_operator, n0, n1);
+    Node* n0 = graph.NewNode(&dummy_operator0);
+    Node* n1 = graph.NewNode(&dummy_operator0);
+    Node* n2 = graph.NewNode(&dummy_operator2, n0, n1);
     n2->TrimInputCount(2);
-    CHECK_EQ(2, n2->InputCount());
-    CHECK_EQ(1, n0->UseCount());
-    CHECK_EQ(1, n1->UseCount());
-    CHECK_EQ(0, n2->UseCount());
+    CHECK_INPUTS(n2, n0, n1);
+    CHECK_USES(n0, n2);
+    CHECK_USES(n1, n2);
   }
 
   {
-    Node* n0 = graph.NewNode(&dummy_operator);
-    Node* n1 = graph.NewNode(&dummy_operator);
-    Node* n2 = graph.NewNode(&dummy_operator, n0, n1);
+    Node* n0 = graph.NewNode(&dummy_operator0);
+    Node* n1 = graph.NewNode(&dummy_operator0);
+    Node* n2 = graph.NewNode(&dummy_operator2, n0, n1);
     n2->TrimInputCount(1);
-    CHECK_EQ(1, n2->InputCount());
-    CHECK_EQ(1, n0->UseCount());
-    CHECK_EQ(0, n1->UseCount());
-    CHECK_EQ(0, n2->UseCount());
+    CHECK_INPUTS(n2, n0);
+    CHECK_USES(n0, n2);
+    CHECK_USES(n1, NONE);
   }
 
   {
-    Node* n0 = graph.NewNode(&dummy_operator);
-    Node* n1 = graph.NewNode(&dummy_operator);
-    Node* n2 = graph.NewNode(&dummy_operator, n0, n1);
+    Node* n0 = graph.NewNode(&dummy_operator0);
+    Node* n1 = graph.NewNode(&dummy_operator0);
+    Node* n2 = graph.NewNode(&dummy_operator2, n0, n1);
     n2->TrimInputCount(0);
-    CHECK_EQ(0, n2->InputCount());
-    CHECK_EQ(0, n0->UseCount());
-    CHECK_EQ(0, n1->UseCount());
-    CHECK_EQ(0, n2->UseCount());
+    CHECK_INPUTS(n2, NONE);
+    CHECK_USES(n0, NONE);
+    CHECK_USES(n1, NONE);
   }
 
   {
-    Node* n0 = graph.NewNode(&dummy_operator);
-    Node* n2 = graph.NewNode(&dummy_operator, n0, n0);
+    Node* n0 = graph.NewNode(&dummy_operator0);
+    Node* n2 = graph.NewNode(&dummy_operator2, n0, n0);
     n2->TrimInputCount(1);
-    CHECK_EQ(1, n2->InputCount());
-    CHECK_EQ(1, n0->UseCount());
-    CHECK_EQ(0, n2->UseCount());
+    CHECK_INPUTS(n2, n0);
+    CHECK_USES(n0, n2);
   }
 
   {
-    Node* n0 = graph.NewNode(&dummy_operator);
-    Node* n2 = graph.NewNode(&dummy_operator, n0, n0);
+    Node* n0 = graph.NewNode(&dummy_operator0);
+    Node* n2 = graph.NewNode(&dummy_operator2, n0, n0);
     n2->TrimInputCount(0);
-    CHECK_EQ(0, n2->InputCount());
-    CHECK_EQ(0, n0->UseCount());
-    CHECK_EQ(0, n2->UseCount());
+    CHECK_INPUTS(n2, NONE);
+    CHECK_USES(n0, NONE);
   }
 }
 
 
 TEST(TrimInputCountOutOfLine1) {
-  GraphTester graph;
+  Zone zone;
+  Graph graph(&zone);
 
   {
-    Node* n0 = graph.NewNode(&dummy_operator);
-    Node* n1 = graph.NewNode(&dummy_operator);
+    Node* n0 = graph.NewNode(&dummy_operator0);
+    Node* n1 = graph.NewNode(&dummy_operator0);
     n1->AppendInput(graph.zone(), n0);
+    CHECK_INPUTS(n1, n0);
+    CHECK_USES(n0, n1);
+
     n1->TrimInputCount(1);
-    CHECK_EQ(1, n1->InputCount());
-    CHECK_EQ(n0, n1->InputAt(0));
-    CHECK_EQ(1, n0->UseCount());
+    CHECK_INPUTS(n1, n0);
+    CHECK_USES(n0, n1);
   }
 
   {
-    Node* n0 = graph.NewNode(&dummy_operator);
-    Node* n1 = graph.NewNode(&dummy_operator);
+    Node* n0 = graph.NewNode(&dummy_operator0);
+    Node* n1 = graph.NewNode(&dummy_operator0);
     n1->AppendInput(graph.zone(), n0);
     CHECK_EQ(1, n1->InputCount());
     n1->TrimInputCount(0);
@@ -648,138 +558,131 @@
   }
 
   {
-    Node* n0 = graph.NewNode(&dummy_operator);
-    Node* n1 = graph.NewNode(&dummy_operator);
-    Node* n2 = graph.NewNode(&dummy_operator);
+    Node* n0 = graph.NewNode(&dummy_operator0);
+    Node* n1 = graph.NewNode(&dummy_operator0);
+    Node* n2 = graph.NewNode(&dummy_operator0);
     n2->AppendInput(graph.zone(), n0);
     n2->AppendInput(graph.zone(), n1);
-    CHECK_EQ(2, n2->InputCount());
+    CHECK_INPUTS(n2, n0, n1);
     n2->TrimInputCount(2);
-    CHECK_EQ(2, n2->InputCount());
-    CHECK_EQ(n0, n2->InputAt(0));
-    CHECK_EQ(n1, n2->InputAt(1));
-    CHECK_EQ(1, n0->UseCount());
-    CHECK_EQ(1, n1->UseCount());
-    CHECK_EQ(0, n2->UseCount());
+    CHECK_INPUTS(n2, n0, n1);
+    CHECK_USES(n0, n2);
+    CHECK_USES(n1, n2);
+    CHECK_USES(n2, NONE);
   }
 
   {
-    Node* n0 = graph.NewNode(&dummy_operator);
-    Node* n1 = graph.NewNode(&dummy_operator);
-    Node* n2 = graph.NewNode(&dummy_operator);
+    Node* n0 = graph.NewNode(&dummy_operator0);
+    Node* n1 = graph.NewNode(&dummy_operator0);
+    Node* n2 = graph.NewNode(&dummy_operator0);
     n2->AppendInput(graph.zone(), n0);
     n2->AppendInput(graph.zone(), n1);
-    CHECK_EQ(2, n2->InputCount());
+    CHECK_INPUTS(n2, n0, n1);
     n2->TrimInputCount(1);
-    CHECK_EQ(1, n2->InputCount());
-    CHECK_EQ(n0, n2->InputAt(0));
-    CHECK_EQ(1, n0->UseCount());
-    CHECK_EQ(0, n1->UseCount());
-    CHECK_EQ(0, n2->UseCount());
+    CHECK_INPUTS(n2, n0);
+    CHECK_USES(n0, n2);
+    CHECK_USES(n1, NONE);
+    CHECK_USES(n2, NONE);
   }
 
   {
-    Node* n0 = graph.NewNode(&dummy_operator);
-    Node* n1 = graph.NewNode(&dummy_operator);
-    Node* n2 = graph.NewNode(&dummy_operator);
+    Node* n0 = graph.NewNode(&dummy_operator0);
+    Node* n1 = graph.NewNode(&dummy_operator0);
+    Node* n2 = graph.NewNode(&dummy_operator0);
     n2->AppendInput(graph.zone(), n0);
     n2->AppendInput(graph.zone(), n1);
-    CHECK_EQ(2, n2->InputCount());
+    CHECK_INPUTS(n2, n0, n1);
     n2->TrimInputCount(0);
-    CHECK_EQ(0, n2->InputCount());
-    CHECK_EQ(0, n0->UseCount());
-    CHECK_EQ(0, n1->UseCount());
-    CHECK_EQ(0, n2->UseCount());
+    CHECK_INPUTS(n2, NONE);
+    CHECK_USES(n0, NONE);
+    CHECK_USES(n1, NONE);
+    CHECK_USES(n2, NONE);
   }
 
   {
-    Node* n0 = graph.NewNode(&dummy_operator);
-    Node* n2 = graph.NewNode(&dummy_operator);
+    Node* n0 = graph.NewNode(&dummy_operator0);
+    Node* n2 = graph.NewNode(&dummy_operator0);
     n2->AppendInput(graph.zone(), n0);
     n2->AppendInput(graph.zone(), n0);
-    CHECK_EQ(2, n2->InputCount());
-    CHECK_EQ(2, n0->UseCount());
+    CHECK_INPUTS(n2, n0, n0);
+    CHECK_USES(n0, n2, n2);
     n2->TrimInputCount(1);
-    CHECK_EQ(1, n2->InputCount());
-    CHECK_EQ(1, n0->UseCount());
-    CHECK_EQ(0, n2->UseCount());
+    CHECK_INPUTS(n2, n0);
+    CHECK_USES(n0, n2);
   }
 
   {
-    Node* n0 = graph.NewNode(&dummy_operator);
-    Node* n2 = graph.NewNode(&dummy_operator);
+    Node* n0 = graph.NewNode(&dummy_operator0);
+    Node* n2 = graph.NewNode(&dummy_operator0);
     n2->AppendInput(graph.zone(), n0);
     n2->AppendInput(graph.zone(), n0);
-    CHECK_EQ(2, n2->InputCount());
-    CHECK_EQ(2, n0->UseCount());
+    CHECK_INPUTS(n2, n0, n0);
+    CHECK_USES(n0, n2, n2);
     n2->TrimInputCount(0);
-    CHECK_EQ(0, n2->InputCount());
-    CHECK_EQ(0, n0->UseCount());
-    CHECK_EQ(0, n2->UseCount());
+    CHECK_INPUTS(n2, NONE);
+    CHECK_USES(n0, NONE);
   }
 }
 
 
 TEST(TrimInputCountOutOfLine2) {
-  GraphTester graph;
+  Zone zone;
+  Graph graph(&zone);
 
   {
-    Node* n0 = graph.NewNode(&dummy_operator);
-    Node* n1 = graph.NewNode(&dummy_operator);
-    Node* n2 = graph.NewNode(&dummy_operator, n0);
+    Node* n0 = graph.NewNode(&dummy_operator0);
+    Node* n1 = graph.NewNode(&dummy_operator0);
+    Node* n2 = graph.NewNode(&dummy_operator1, n0);
     n2->AppendInput(graph.zone(), n1);
-    CHECK_EQ(2, n2->InputCount());
+    CHECK_INPUTS(n2, n0, n1);
     n2->TrimInputCount(2);
-    CHECK_EQ(2, n2->InputCount());
-    CHECK_EQ(n0, n2->InputAt(0));
-    CHECK_EQ(n1, n2->InputAt(1));
-    CHECK_EQ(1, n0->UseCount());
-    CHECK_EQ(1, n1->UseCount());
-    CHECK_EQ(0, n2->UseCount());
+    CHECK_INPUTS(n2, n0, n1);
+    CHECK_USES(n0, n2);
+    CHECK_USES(n1, n2);
+    CHECK_USES(n2, NONE);
   }
 
   {
-    Node* n0 = graph.NewNode(&dummy_operator);
-    Node* n1 = graph.NewNode(&dummy_operator);
-    Node* n2 = graph.NewNode(&dummy_operator, n0);
+    Node* n0 = graph.NewNode(&dummy_operator0);
+    Node* n1 = graph.NewNode(&dummy_operator0);
+    Node* n2 = graph.NewNode(&dummy_operator1, n0);
     n2->AppendInput(graph.zone(), n1);
-    CHECK_EQ(2, n2->InputCount());
+    CHECK_INPUTS(n2, n0, n1);
     n2->TrimInputCount(1);
-    CHECK_EQ(1, n2->InputCount());
-    CHECK_EQ(n0, n2->InputAt(0));
-    CHECK_EQ(1, n0->UseCount());
-    CHECK_EQ(0, n1->UseCount());
-    CHECK_EQ(0, n2->UseCount());
+    CHECK_INPUTS(n2, n0);
+    CHECK_USES(n0, n2);
+    CHECK_USES(n1, NONE);
+    CHECK_USES(n2, NONE);
   }
 
   {
-    Node* n0 = graph.NewNode(&dummy_operator);
-    Node* n1 = graph.NewNode(&dummy_operator);
-    Node* n2 = graph.NewNode(&dummy_operator, n0);
+    Node* n0 = graph.NewNode(&dummy_operator0);
+    Node* n1 = graph.NewNode(&dummy_operator0);
+    Node* n2 = graph.NewNode(&dummy_operator1, n0);
     n2->AppendInput(graph.zone(), n1);
-    CHECK_EQ(2, n2->InputCount());
+    CHECK_INPUTS(n2, n0, n1);
     n2->TrimInputCount(0);
-    CHECK_EQ(0, n2->InputCount());
-    CHECK_EQ(0, n0->UseCount());
-    CHECK_EQ(0, n1->UseCount());
-    CHECK_EQ(0, n2->UseCount());
+    CHECK_INPUTS(n2, NONE);
+    CHECK_USES(n0, NONE);
+    CHECK_USES(n1, NONE);
+    CHECK_USES(n2, NONE);
   }
 
   {
-    Node* n0 = graph.NewNode(&dummy_operator);
-    Node* n2 = graph.NewNode(&dummy_operator, n0);
+    Node* n0 = graph.NewNode(&dummy_operator0);
+    Node* n2 = graph.NewNode(&dummy_operator1, n0);
     n2->AppendInput(graph.zone(), n0);
-    CHECK_EQ(2, n2->InputCount());
-    CHECK_EQ(2, n0->UseCount());
+    CHECK_INPUTS(n2, n0, n0);
+    CHECK_USES(n0, n2, n2);
     n2->TrimInputCount(1);
-    CHECK_EQ(1, n2->InputCount());
-    CHECK_EQ(1, n0->UseCount());
-    CHECK_EQ(0, n2->UseCount());
+    CHECK_INPUTS(n2, n0);
+    CHECK_USES(n0, n2);
+    CHECK_USES(n2, NONE);
   }
 
   {
-    Node* n0 = graph.NewNode(&dummy_operator);
-    Node* n2 = graph.NewNode(&dummy_operator, n0);
+    Node* n0 = graph.NewNode(&dummy_operator0);
+    Node* n2 = graph.NewNode(&dummy_operator1, n0);
     n2->AppendInput(graph.zone(), n0);
     CHECK_EQ(2, n2->InputCount());
     CHECK_EQ(2, n0->UseCount());
@@ -791,48 +694,96 @@
 }
 
 
-TEST(RemoveAllInputs) {
-  GraphTester graph;
+TEST(NullAllInputs) {
+  Zone zone;
+  Graph graph(&zone);
 
   for (int i = 0; i < 2; i++) {
-    Node* n0 = graph.NewNode(&dummy_operator);
-    Node* n1 = graph.NewNode(&dummy_operator, n0);
+    Node* n0 = graph.NewNode(&dummy_operator0);
+    Node* n1 = graph.NewNode(&dummy_operator1, n0);
     Node* n2;
     if (i == 0) {
-      n2 = graph.NewNode(&dummy_operator, n0, n1);
+      n2 = graph.NewNode(&dummy_operator2, n0, n1);
+      CHECK_INPUTS(n2, n0, n1);
     } else {
-      n2 = graph.NewNode(&dummy_operator, n0);
+      n2 = graph.NewNode(&dummy_operator1, n0);
+      CHECK_INPUTS(n2, n0);
       n2->AppendInput(graph.zone(), n1);  // with out-of-line input.
+      CHECK_INPUTS(n2, n0, n1);
     }
 
-    n0->RemoveAllInputs();
-    CHECK_EQ(0, n0->InputCount());
+    n0->NullAllInputs();
+    CHECK_INPUTS(n0, NONE);
 
-    CHECK_EQ(2, n0->UseCount());
-    n1->RemoveAllInputs();
-    CHECK_EQ(1, n1->InputCount());
-    CHECK_EQ(1, n0->UseCount());
-    CHECK_EQ(NULL, n1->InputAt(0));
+    CHECK_USES(n0, n1, n2);
+    n1->NullAllInputs();
+    CHECK_INPUTS(n1, NULL);
+    CHECK_INPUTS(n2, n0, n1);
+    CHECK_USES(n0, n2);
 
-    CHECK_EQ(1, n1->UseCount());
-    n2->RemoveAllInputs();
-    CHECK_EQ(2, n2->InputCount());
-    CHECK_EQ(0, n0->UseCount());
-    CHECK_EQ(0, n1->UseCount());
-    CHECK_EQ(NULL, n2->InputAt(0));
-    CHECK_EQ(NULL, n2->InputAt(1));
+    n2->NullAllInputs();
+    CHECK_INPUTS(n1, NULL);
+    CHECK_INPUTS(n2, NULL, NULL);
+    CHECK_USES(n0, NONE);
   }
 
   {
-    Node* n0 = graph.NewNode(&dummy_operator);
-    Node* n1 = graph.NewNode(&dummy_operator, n0);
+    Node* n0 = graph.NewNode(&dummy_operator0);
+    Node* n1 = graph.NewNode(&dummy_operator1, n0);
     n1->ReplaceInput(0, n1);  // self-reference.
 
-    CHECK_EQ(0, n0->UseCount());
-    CHECK_EQ(1, n1->UseCount());
-    n1->RemoveAllInputs();
-    CHECK_EQ(1, n1->InputCount());
-    CHECK_EQ(0, n1->UseCount());
-    CHECK_EQ(NULL, n1->InputAt(0));
+    CHECK_INPUTS(n0, NONE);
+    CHECK_INPUTS(n1, n1);
+    CHECK_USES(n0, NONE);
+    CHECK_USES(n1, n1);
+    n1->NullAllInputs();
+
+    CHECK_INPUTS(n0, NONE);
+    CHECK_INPUTS(n1, NULL);
+    CHECK_USES(n0, NONE);
+    CHECK_USES(n1, NONE);
   }
 }
+
+
+TEST(AppendAndTrim) {
+  Zone zone;
+  Graph graph(&zone);
+
+  Node* nodes[] = {
+      graph.NewNode(&dummy_operator0), graph.NewNode(&dummy_operator0),
+      graph.NewNode(&dummy_operator0), graph.NewNode(&dummy_operator0),
+      graph.NewNode(&dummy_operator0)};
+
+  int max = static_cast<int>(arraysize(nodes));
+
+  Node* last = graph.NewNode(&dummy_operator0);
+
+  for (int i = 0; i < max; i++) {
+    last->AppendInput(graph.zone(), nodes[i]);
+    CheckInputs(last, nodes, i + 1);
+
+    for (int j = 0; j < max; j++) {
+      if (j <= i) CHECK_USES(nodes[j], last);
+      if (j > i) CHECK_USES(nodes[j], NONE);
+    }
+
+    CHECK_USES(last, NONE);
+  }
+
+  for (int i = max; i >= 0; i--) {
+    last->TrimInputCount(i);
+    CheckInputs(last, nodes, i);
+
+    for (int j = 0; j < i; j++) {
+      if (j < i) CHECK_USES(nodes[j], last);
+      if (j >= i) CHECK_USES(nodes[j], NONE);
+    }
+
+    CHECK_USES(last, NONE);
+  }
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/test/cctest/compiler/test-operator.cc b/test/cctest/compiler/test-operator.cc
index 39f660f..eecf46a 100644
--- a/test/cctest/compiler/test-operator.cc
+++ b/test/cctest/compiler/test-operator.cc
@@ -4,13 +4,12 @@
 
 #include <sstream>
 
-#include "src/v8.h"
-
 #include "src/compiler/operator.h"
 #include "test/cctest/cctest.h"
 
-using namespace v8::internal;
-using namespace v8::internal::compiler;
+namespace v8 {
+namespace internal {
+namespace compiler {
 
 #define NONE Operator::kNoProperties
 #define FOLD Operator::kFoldable
@@ -69,10 +68,10 @@
 }
 
 
-static SmartArrayPointer<const char> OperatorToString(Operator* op) {
+static v8::base::SmartArrayPointer<const char> OperatorToString(Operator* op) {
   std::ostringstream os;
   os << *op;
-  return SmartArrayPointer<const char>(StrDup(os.str().c_str()));
+  return v8::base::SmartArrayPointer<const char>(StrDup(os.str().c_str()));
 }
 
 
@@ -80,14 +79,14 @@
   Operator op1a(19, NONE, "Another1", 0, 0, 0, 0, 0, 0);
   Operator op1b(19, FOLD, "Another2", 2, 0, 0, 2, 0, 0);
 
-  CHECK_EQ("Another1", OperatorToString(&op1a).get());
-  CHECK_EQ("Another2", OperatorToString(&op1b).get());
+  CHECK_EQ(0, strcmp("Another1", OperatorToString(&op1a).get()));
+  CHECK_EQ(0, strcmp("Another2", OperatorToString(&op1b).get()));
 
   Operator op2a(20, NONE, "Flog1", 0, 0, 0, 0, 0, 0);
   Operator op2b(20, FOLD, "Flog2", 1, 0, 0, 1, 0, 0);
 
-  CHECK_EQ("Flog1", OperatorToString(&op2a).get());
-  CHECK_EQ("Flog2", OperatorToString(&op2b).get());
+  CHECK_EQ(0, strcmp("Flog1", OperatorToString(&op2a).get()));
+  CHECK_EQ(0, strcmp("Flog2", OperatorToString(&op2b).get()));
 }
 
 
@@ -148,16 +147,16 @@
 
 TEST(TestOperator1int_Print) {
   Operator1<int> op1(12, NONE, "Op1Test", 0, 0, 0, 1, 0, 0, 0);
-  CHECK_EQ("Op1Test[0]", OperatorToString(&op1).get());
+  CHECK_EQ(0, strcmp("Op1Test[0]", OperatorToString(&op1).get()));
 
   Operator1<int> op2(12, NONE, "Op1Test", 0, 0, 0, 1, 0, 0, 66666666);
-  CHECK_EQ("Op1Test[66666666]", OperatorToString(&op2).get());
+  CHECK_EQ(0, strcmp("Op1Test[66666666]", OperatorToString(&op2).get()));
 
   Operator1<int> op3(12, NONE, "FooBar", 0, 0, 0, 1, 0, 0, 2347);
-  CHECK_EQ("FooBar[2347]", OperatorToString(&op3).get());
+  CHECK_EQ(0, strcmp("FooBar[2347]", OperatorToString(&op3).get()));
 
   Operator1<int> op4(12, NONE, "BarFoo", 0, 0, 0, 1, 0, 0, -879);
-  CHECK_EQ("BarFoo[-879]", OperatorToString(&op4).get());
+  CHECK_EQ(0, strcmp("BarFoo[-879]", OperatorToString(&op4).get()));
 }
 
 
@@ -179,8 +178,8 @@
   Operator1<double> op1a(23, NONE, "Canary", 0, 0, 0, 0, 0, 0, 0.5);
   Operator1<double> op1b(23, FOLD, "Finch", 2, 0, 0, 2, 0, 0, -1.5);
 
-  CHECK_EQ("Canary[0.5]", OperatorToString(&op1a).get());
-  CHECK_EQ("Finch[-1.5]", OperatorToString(&op1b).get());
+  CHECK_EQ(0, strcmp("Canary[0.5]", OperatorToString(&op1a).get()));
+  CHECK_EQ(0, strcmp("Finch[-1.5]", OperatorToString(&op1b).get()));
 }
 
 
@@ -281,3 +280,7 @@
   CHECK_EQ(55, op.EffectOutputCount());
   CHECK_EQ(66, op.ControlOutputCount());
 }
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/test/cctest/compiler/test-osr.cc b/test/cctest/compiler/test-osr.cc
new file mode 100644
index 0000000..f0640c2
--- /dev/null
+++ b/test/cctest/compiler/test-osr.cc
@@ -0,0 +1,575 @@
+// Copyright 2015 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/codegen.h"
+#include "src/compiler/all-nodes.h"
+#include "src/compiler/common-operator.h"
+#include "src/compiler/diamond.h"
+#include "src/compiler/graph.h"
+#include "src/compiler/js-graph.h"
+#include "src/compiler/js-operator.h"
+#include "src/compiler/operator.h"
+#include "src/compiler/osr.h"
+#include "test/cctest/cctest.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+// TODO(titzer): move this method to a common testing place.
+
+static int CheckInputs(Node* node, Node* i0 = NULL, Node* i1 = NULL,
+                       Node* i2 = NULL, Node* i3 = NULL) {
+  int count = 4;
+  if (i3 == NULL) count = 3;
+  if (i2 == NULL) count = 2;
+  if (i1 == NULL) count = 1;
+  if (i0 == NULL) count = 0;
+  CHECK_EQ(count, node->InputCount());
+  if (i0 != NULL) CHECK_EQ(i0, node->InputAt(0));
+  if (i1 != NULL) CHECK_EQ(i1, node->InputAt(1));
+  if (i2 != NULL) CHECK_EQ(i2, node->InputAt(2));
+  if (i3 != NULL) CHECK_EQ(i3, node->InputAt(3));
+  return count;
+}
+
+
+static Operator kIntLt(IrOpcode::kInt32LessThan, Operator::kPure,
+                       "Int32LessThan", 2, 0, 0, 1, 0, 0);
+static Operator kIntAdd(IrOpcode::kInt32Add, Operator::kPure, "Int32Add", 2, 0,
+                        0, 1, 0, 0);
+
+
+static const int kMaxOsrValues = 10;
+
+class OsrDeconstructorTester : public HandleAndZoneScope {
+ public:
+  explicit OsrDeconstructorTester(int num_values)
+      : isolate(main_isolate()),
+        common(main_zone()),
+        graph(main_zone()),
+        jsgraph(main_isolate(), &graph, &common, nullptr, nullptr, nullptr),
+        start(graph.NewNode(common.Start(1))),
+        p0(graph.NewNode(common.Parameter(0), start)),
+        end(graph.NewNode(common.End(1), start)),
+        osr_normal_entry(graph.NewNode(common.OsrNormalEntry(), start, start)),
+        osr_loop_entry(graph.NewNode(common.OsrLoopEntry(), start, start)),
+        self(graph.NewNode(common.Int32Constant(0xaabbccdd))) {
+    CHECK(num_values <= kMaxOsrValues);
+    graph.SetStart(start);
+    for (int i = 0; i < num_values; i++) {
+      osr_values[i] = graph.NewNode(common.OsrValue(i), osr_loop_entry);
+    }
+  }
+
+  Isolate* isolate;
+  CommonOperatorBuilder common;
+  Graph graph;
+  JSGraph jsgraph;
+  Node* start;
+  Node* p0;
+  Node* end;
+  Node* osr_normal_entry;
+  Node* osr_loop_entry;
+  Node* self;
+  Node* osr_values[kMaxOsrValues];
+
+  Node* NewOsrPhi(Node* loop, Node* incoming, int osr_value, Node* back1 = NULL,
+                  Node* back2 = NULL, Node* back3 = NULL) {
+    int count = 5;
+    if (back3 == NULL) count = 4;
+    if (back2 == NULL) count = 3;
+    if (back1 == NULL) count = 2;
+    CHECK_EQ(loop->InputCount(), count);
+    CHECK_EQ(osr_loop_entry, loop->InputAt(1));
+
+    Node* inputs[6];
+    inputs[0] = incoming;
+    inputs[1] = osr_values[osr_value];
+    if (count > 2) inputs[2] = back1;
+    if (count > 3) inputs[3] = back2;
+    if (count > 4) inputs[4] = back3;
+    inputs[count] = loop;
+    return graph.NewNode(common.Phi(MachineRepresentation::kTagged, count),
+                         count + 1, inputs);
+  }
+
+  Node* NewLoop(bool is_osr, int num_backedges, Node* entry = nullptr) {
+    if (entry == nullptr) entry = osr_normal_entry;
+    Node* loop = graph.NewNode(common.Loop(1), entry);
+    if (is_osr) {
+      loop->AppendInput(graph.zone(), osr_loop_entry);
+    }
+    for (int i = 0; i < num_backedges; i++) {
+      loop->AppendInput(graph.zone(), loop);
+    }
+    NodeProperties::ChangeOp(loop, common.Loop(loop->InputCount()));
+    return loop;
+  }
+
+  Node* NewOsrLoop(int num_backedges, Node* entry = NULL) {
+    return NewLoop(true, num_backedges, entry);
+  }
+
+  void DeconstructOsr() {
+    OsrHelper helper(0, 0);
+    helper.Deconstruct(&jsgraph, &common, main_zone());
+    AllNodes nodes(main_zone(), &graph);
+    // Should be edited out.
+    CHECK(!nodes.IsLive(osr_normal_entry));
+    CHECK(!nodes.IsLive(osr_loop_entry));
+    // No dangling nodes should be left over.
+    for (Node* const node : nodes.live) {
+      for (Node* const use : node->uses()) {
+        CHECK(std::find(nodes.live.begin(), nodes.live.end(), use) !=
+              nodes.live.end());
+      }
+    }
+  }
+};
+
+
+TEST(Deconstruct_osr0) {
+  OsrDeconstructorTester T(0);
+
+  Node* loop = T.NewOsrLoop(1);
+
+  T.graph.SetEnd(loop);
+
+  T.DeconstructOsr();
+
+  CheckInputs(loop, T.start, loop);
+}
+
+
+TEST(Deconstruct_osr1) {
+  OsrDeconstructorTester T(1);
+
+  Node* loop = T.NewOsrLoop(1);
+  Node* osr_phi =
+      T.NewOsrPhi(loop, T.jsgraph.OneConstant(), 0, T.jsgraph.ZeroConstant());
+
+  Node* ret = T.graph.NewNode(T.common.Return(), osr_phi, T.start, loop);
+  T.graph.SetEnd(ret);
+
+  T.DeconstructOsr();
+
+  CheckInputs(loop, T.start, loop);
+  CheckInputs(osr_phi, T.osr_values[0], T.jsgraph.ZeroConstant(), loop);
+  CheckInputs(ret, osr_phi, T.start, loop);
+}
+
+
+TEST(Deconstruct_osr_remove_prologue) {
+  OsrDeconstructorTester T(1);
+  Diamond d(&T.graph, &T.common, T.p0);
+  d.Chain(T.osr_normal_entry);
+
+  Node* loop = T.NewOsrLoop(1, d.merge);
+  Node* osr_phi =
+      T.NewOsrPhi(loop, T.jsgraph.OneConstant(), 0, T.jsgraph.ZeroConstant());
+
+  Node* ret = T.graph.NewNode(T.common.Return(), osr_phi, T.start, loop);
+  T.graph.SetEnd(ret);
+
+  T.DeconstructOsr();
+
+  CheckInputs(loop, T.start, loop);
+  CheckInputs(osr_phi, T.osr_values[0], T.jsgraph.ZeroConstant(), loop);
+  CheckInputs(ret, osr_phi, T.start, loop);
+
+  // The control before the loop should have been removed.
+  AllNodes nodes(T.main_zone(), &T.graph);
+  CHECK(!nodes.IsLive(d.branch));
+  CHECK(!nodes.IsLive(d.if_true));
+  CHECK(!nodes.IsLive(d.if_false));
+  CHECK(!nodes.IsLive(d.merge));
+}
+
+
+TEST(Deconstruct_osr_with_body1) {
+  OsrDeconstructorTester T(1);
+
+  Node* loop = T.NewOsrLoop(1);
+
+  Node* branch = T.graph.NewNode(T.common.Branch(), T.p0, loop);
+  Node* if_true = T.graph.NewNode(T.common.IfTrue(), branch);
+  Node* if_false = T.graph.NewNode(T.common.IfFalse(), branch);
+  loop->ReplaceInput(2, if_true);
+
+  Node* osr_phi =
+      T.NewOsrPhi(loop, T.jsgraph.OneConstant(), 0, T.jsgraph.ZeroConstant());
+
+  Node* ret = T.graph.NewNode(T.common.Return(), osr_phi, T.start, if_false);
+  T.graph.SetEnd(ret);
+
+  T.DeconstructOsr();
+
+  CheckInputs(loop, T.start, if_true);
+  CheckInputs(branch, T.p0, loop);
+  CheckInputs(if_true, branch);
+  CheckInputs(if_false, branch);
+  CheckInputs(osr_phi, T.osr_values[0], T.jsgraph.ZeroConstant(), loop);
+  CheckInputs(ret, osr_phi, T.start, if_false);
+}
+
+
+TEST(Deconstruct_osr_with_body2) {
+  OsrDeconstructorTester T(1);
+
+  Node* loop = T.NewOsrLoop(1);
+
+  // Two chained branches in the the body of the loop.
+  Node* branch1 = T.graph.NewNode(T.common.Branch(), T.p0, loop);
+  Node* if_true1 = T.graph.NewNode(T.common.IfTrue(), branch1);
+  Node* if_false1 = T.graph.NewNode(T.common.IfFalse(), branch1);
+
+  Node* branch2 = T.graph.NewNode(T.common.Branch(), T.p0, if_true1);
+  Node* if_true2 = T.graph.NewNode(T.common.IfTrue(), branch2);
+  Node* if_false2 = T.graph.NewNode(T.common.IfFalse(), branch2);
+  loop->ReplaceInput(2, if_true2);
+
+  Node* osr_phi =
+      T.NewOsrPhi(loop, T.jsgraph.OneConstant(), 0, T.jsgraph.ZeroConstant());
+
+  Node* merge = T.graph.NewNode(T.common.Merge(2), if_false1, if_false2);
+  Node* ret = T.graph.NewNode(T.common.Return(), osr_phi, T.start, merge);
+  T.graph.SetEnd(ret);
+
+  T.DeconstructOsr();
+
+  CheckInputs(loop, T.start, if_true2);
+  CheckInputs(branch1, T.p0, loop);
+  CheckInputs(branch2, T.p0, if_true1);
+  CheckInputs(if_true1, branch1);
+  CheckInputs(if_false1, branch1);
+  CheckInputs(if_true2, branch2);
+  CheckInputs(if_false2, branch2);
+
+  CheckInputs(osr_phi, T.osr_values[0], T.jsgraph.ZeroConstant(), loop);
+  CheckInputs(ret, osr_phi, T.start, merge);
+  CheckInputs(merge, if_false1, if_false2);
+}
+
+
+TEST(Deconstruct_osr_with_body3) {
+  OsrDeconstructorTester T(1);
+
+  Node* loop = T.NewOsrLoop(2);
+
+  // Two branches that create two different backedges.
+  Node* branch1 = T.graph.NewNode(T.common.Branch(), T.p0, loop);
+  Node* if_true1 = T.graph.NewNode(T.common.IfTrue(), branch1);
+  Node* if_false1 = T.graph.NewNode(T.common.IfFalse(), branch1);
+
+  Node* branch2 = T.graph.NewNode(T.common.Branch(), T.p0, if_true1);
+  Node* if_true2 = T.graph.NewNode(T.common.IfTrue(), branch2);
+  Node* if_false2 = T.graph.NewNode(T.common.IfFalse(), branch2);
+  loop->ReplaceInput(2, if_false1);
+  loop->ReplaceInput(3, if_true2);
+
+  Node* osr_phi =
+      T.NewOsrPhi(loop, T.jsgraph.OneConstant(), 0, T.jsgraph.ZeroConstant(),
+                  T.jsgraph.ZeroConstant());
+
+  Node* ret = T.graph.NewNode(T.common.Return(), osr_phi, T.start, if_false2);
+  T.graph.SetEnd(ret);
+
+  T.DeconstructOsr();
+
+  CheckInputs(loop, T.start, if_false1, if_true2);
+  CheckInputs(branch1, T.p0, loop);
+  CheckInputs(branch2, T.p0, if_true1);
+  CheckInputs(if_true1, branch1);
+  CheckInputs(if_false1, branch1);
+  CheckInputs(if_true2, branch2);
+  CheckInputs(if_false2, branch2);
+
+  CheckInputs(osr_phi, T.osr_values[0], T.jsgraph.ZeroConstant(),
+              T.jsgraph.ZeroConstant(), loop);
+  CheckInputs(ret, osr_phi, T.start, if_false2);
+}
+
+
+struct While {
+  OsrDeconstructorTester& t;
+  Node* branch;
+  Node* if_true;
+  Node* exit;
+  Node* loop;
+
+  While(OsrDeconstructorTester& R, Node* cond, bool is_osr, int backedges = 1)
+      : t(R) {
+    loop = t.NewLoop(is_osr, backedges);
+    branch = t.graph.NewNode(t.common.Branch(), cond, loop);
+    if_true = t.graph.NewNode(t.common.IfTrue(), branch);
+    exit = t.graph.NewNode(t.common.IfFalse(), branch);
+    loop->ReplaceInput(loop->InputCount() - 1, if_true);
+  }
+
+  void Nest(While& that) {
+    that.loop->ReplaceInput(that.loop->InputCount() - 1, exit);
+    this->loop->ReplaceInput(0, that.if_true);
+  }
+
+  Node* Phi(Node* i1, Node* i2, Node* i3) {
+    if (loop->InputCount() == 2) {
+      return t.graph.NewNode(t.common.Phi(MachineRepresentation::kTagged, 2),
+                             i1, i2, loop);
+    } else {
+      return t.graph.NewNode(t.common.Phi(MachineRepresentation::kTagged, 3),
+                             i1, i2, i3, loop);
+    }
+  }
+};
+
+
+static Node* FindSuccessor(Node* node, IrOpcode::Value opcode) {
+  for (Node* use : node->uses()) {
+    if (use->opcode() == opcode) return use;
+  }
+  UNREACHABLE();  // should have been found.
+  return nullptr;
+}
+
+
+TEST(Deconstruct_osr_nested1) {
+  OsrDeconstructorTester T(1);
+
+  While outer(T, T.p0, false);
+  While inner(T, T.p0, true);
+  inner.Nest(outer);
+
+  Node* outer_phi = outer.Phi(T.p0, T.p0, nullptr);
+  outer.branch->ReplaceInput(0, outer_phi);
+
+  Node* osr_phi = inner.Phi(T.jsgraph.TrueConstant(), T.osr_values[0],
+                            T.jsgraph.FalseConstant());
+  inner.branch->ReplaceInput(0, osr_phi);
+  outer_phi->ReplaceInput(1, osr_phi);
+
+  Node* ret =
+      T.graph.NewNode(T.common.Return(), outer_phi, T.start, outer.exit);
+  Node* end = T.graph.NewNode(T.common.End(1), ret);
+  T.graph.SetEnd(end);
+
+  T.DeconstructOsr();
+
+  // Check structure of deconstructed graph.
+  // Check inner OSR loop is directly connected to start.
+  CheckInputs(inner.loop, T.start, inner.if_true);
+  CheckInputs(osr_phi, T.osr_values[0], T.jsgraph.FalseConstant(), inner.loop);
+
+  // Check control transfer to copy of outer loop.
+  Node* new_outer_loop = FindSuccessor(inner.exit, IrOpcode::kLoop);
+  Node* new_outer_phi = FindSuccessor(new_outer_loop, IrOpcode::kPhi);
+  CHECK_NE(new_outer_loop, outer.loop);
+  CHECK_NE(new_outer_phi, outer_phi);
+
+  CheckInputs(new_outer_loop, inner.exit, new_outer_loop->InputAt(1));
+
+  // Check structure of outer loop.
+  Node* new_outer_branch = FindSuccessor(new_outer_loop, IrOpcode::kBranch);
+  CHECK_NE(new_outer_branch, outer.branch);
+  CheckInputs(new_outer_branch, new_outer_phi, new_outer_loop);
+  Node* new_outer_exit = FindSuccessor(new_outer_branch, IrOpcode::kIfFalse);
+  Node* new_outer_if_true = FindSuccessor(new_outer_branch, IrOpcode::kIfTrue);
+
+  // Check structure of return.
+  end = T.graph.end();
+  Node* new_ret = end->InputAt(0);
+  CHECK_EQ(IrOpcode::kReturn, new_ret->opcode());
+  CheckInputs(new_ret, new_outer_phi, T.start, new_outer_exit);
+
+  // Check structure of inner loop.
+  Node* new_inner_loop = FindSuccessor(new_outer_if_true, IrOpcode::kLoop);
+  Node* new_inner_phi = FindSuccessor(new_inner_loop, IrOpcode::kPhi);
+
+  CheckInputs(new_inner_phi, T.jsgraph.TrueConstant(),
+              T.jsgraph.FalseConstant(), new_inner_loop);
+  CheckInputs(new_outer_phi, osr_phi, new_inner_phi, new_outer_loop);
+}
+
+
+TEST(Deconstruct_osr_nested2) {
+  OsrDeconstructorTester T(1);
+
+  // Test multiple backedge outer loop.
+  While outer(T, T.p0, false, 2);
+  While inner(T, T.p0, true);
+  inner.Nest(outer);
+
+  Node* outer_phi = outer.Phi(T.p0, T.p0, T.p0);
+  outer.branch->ReplaceInput(0, outer_phi);
+
+  Node* osr_phi = inner.Phi(T.jsgraph.TrueConstant(), T.osr_values[0],
+                            T.jsgraph.FalseConstant());
+  inner.branch->ReplaceInput(0, osr_phi);
+  outer_phi->ReplaceInput(1, osr_phi);
+  outer_phi->ReplaceInput(2, T.jsgraph.FalseConstant());
+
+  Node* x_branch = T.graph.NewNode(T.common.Branch(), osr_phi, inner.exit);
+  Node* x_true = T.graph.NewNode(T.common.IfTrue(), x_branch);
+  Node* x_false = T.graph.NewNode(T.common.IfFalse(), x_branch);
+
+  outer.loop->ReplaceInput(1, x_true);
+  outer.loop->ReplaceInput(2, x_false);
+
+  Node* ret =
+      T.graph.NewNode(T.common.Return(), outer_phi, T.start, outer.exit);
+  Node* end = T.graph.NewNode(T.common.End(1), ret);
+  T.graph.SetEnd(end);
+
+  T.DeconstructOsr();
+
+  // Check structure of deconstructed graph.
+  // Check inner OSR loop is directly connected to start.
+  CheckInputs(inner.loop, T.start, inner.if_true);
+  CheckInputs(osr_phi, T.osr_values[0], T.jsgraph.FalseConstant(), inner.loop);
+
+  // Check control transfer to copy of outer loop.
+  Node* new_merge = FindSuccessor(x_true, IrOpcode::kMerge);
+  CHECK_EQ(new_merge, FindSuccessor(x_false, IrOpcode::kMerge));
+  CheckInputs(new_merge, x_true, x_false);
+
+  Node* new_outer_loop = FindSuccessor(new_merge, IrOpcode::kLoop);
+  Node* new_outer_phi = FindSuccessor(new_outer_loop, IrOpcode::kPhi);
+  CHECK_NE(new_outer_loop, outer.loop);
+  CHECK_NE(new_outer_phi, outer_phi);
+
+  Node* new_entry_phi = FindSuccessor(new_merge, IrOpcode::kPhi);
+  CheckInputs(new_entry_phi, osr_phi, T.jsgraph.FalseConstant(), new_merge);
+
+  CHECK_EQ(new_merge, new_outer_loop->InputAt(0));
+
+  // Check structure of outer loop.
+  Node* new_outer_branch = FindSuccessor(new_outer_loop, IrOpcode::kBranch);
+  CHECK_NE(new_outer_branch, outer.branch);
+  CheckInputs(new_outer_branch, new_outer_phi, new_outer_loop);
+  Node* new_outer_exit = FindSuccessor(new_outer_branch, IrOpcode::kIfFalse);
+  Node* new_outer_if_true = FindSuccessor(new_outer_branch, IrOpcode::kIfTrue);
+
+  // Check structure of return.
+  end = T.graph.end();
+  Node* new_ret = end->InputAt(0);
+  CHECK_EQ(IrOpcode::kReturn, new_ret->opcode());
+  CheckInputs(new_ret, new_outer_phi, T.start, new_outer_exit);
+
+  // Check structure of inner loop.
+  Node* new_inner_loop = FindSuccessor(new_outer_if_true, IrOpcode::kLoop);
+  Node* new_inner_phi = FindSuccessor(new_inner_loop, IrOpcode::kPhi);
+
+  CheckInputs(new_inner_phi, T.jsgraph.TrueConstant(),
+              T.jsgraph.FalseConstant(), new_inner_loop);
+  CheckInputs(new_outer_phi, new_entry_phi, new_inner_phi,
+              T.jsgraph.FalseConstant(), new_outer_loop);
+}
+
+
+Node* MakeCounter(JSGraph* jsgraph, Node* start, Node* loop) {
+  int count = loop->InputCount();
+  NodeVector tmp_inputs(jsgraph->graph()->zone());
+  for (int i = 0; i < count; i++) {
+    tmp_inputs.push_back(start);
+  }
+  tmp_inputs.push_back(loop);
+
+  Node* phi = jsgraph->graph()->NewNode(
+      jsgraph->common()->Phi(MachineRepresentation::kWord32, count), count + 1,
+      &tmp_inputs[0]);
+  Node* inc = jsgraph->graph()->NewNode(&kIntAdd, phi, jsgraph->OneConstant());
+
+  for (int i = 1; i < count; i++) {
+    phi->ReplaceInput(i, inc);
+  }
+  return phi;
+}
+
+
+TEST(Deconstruct_osr_nested3) {
+  OsrDeconstructorTester T(1);
+
+  // outermost loop.
+  While loop0(T, T.p0, false, 1);
+  Node* loop0_cntr = MakeCounter(&T.jsgraph, T.p0, loop0.loop);
+  loop0.branch->ReplaceInput(0, loop0_cntr);
+
+  // middle loop.
+  Node* loop1 = T.graph.NewNode(T.common.Loop(1), loop0.if_true);
+  Node* loop1_phi =
+      T.graph.NewNode(T.common.Phi(MachineRepresentation::kTagged, 2),
+                      loop0_cntr, loop0_cntr, loop1);
+
+  // innermost (OSR) loop.
+  While loop2(T, T.p0, true, 1);
+  loop2.loop->ReplaceInput(0, loop1);
+
+  Node* loop2_cntr = MakeCounter(&T.jsgraph, loop1_phi, loop2.loop);
+  loop2_cntr->ReplaceInput(1, T.osr_values[0]);
+  Node* osr_phi = loop2_cntr;
+  Node* loop2_inc = loop2_cntr->InputAt(2);
+  loop2.branch->ReplaceInput(0, loop2_cntr);
+
+  loop1_phi->ReplaceInput(1, loop2_cntr);
+  loop0_cntr->ReplaceInput(1, loop2_cntr);
+
+  // Branch to either the outer or middle loop.
+  Node* branch = T.graph.NewNode(T.common.Branch(), loop2_cntr, loop2.exit);
+  Node* if_true = T.graph.NewNode(T.common.IfTrue(), branch);
+  Node* if_false = T.graph.NewNode(T.common.IfFalse(), branch);
+
+  loop0.loop->ReplaceInput(1, if_true);
+  loop1->AppendInput(T.graph.zone(), if_false);
+  NodeProperties::ChangeOp(loop1, T.common.Loop(2));
+
+  Node* ret =
+      T.graph.NewNode(T.common.Return(), loop0_cntr, T.start, loop0.exit);
+  Node* end = T.graph.NewNode(T.common.End(1), ret);
+  T.graph.SetEnd(end);
+
+  T.DeconstructOsr();
+
+  // Check structure of deconstructed graph.
+  // Check loop2 (OSR loop) is directly connected to start.
+  CheckInputs(loop2.loop, T.start, loop2.if_true);
+  CheckInputs(osr_phi, T.osr_values[0], loop2_inc, loop2.loop);
+  CheckInputs(loop2.branch, osr_phi, loop2.loop);
+  CheckInputs(loop2.if_true, loop2.branch);
+  CheckInputs(loop2.exit, loop2.branch);
+  CheckInputs(branch, osr_phi, loop2.exit);
+  CheckInputs(if_true, branch);
+  CheckInputs(if_false, branch);
+
+  // Check structure of new_loop1.
+  Node* new_loop1_loop = FindSuccessor(if_false, IrOpcode::kLoop);
+  // TODO(titzer): check the internal copy of loop2.
+  USE(new_loop1_loop);
+
+  // Check structure of new_loop0.
+  Node* new_loop0_loop_entry = FindSuccessor(if_true, IrOpcode::kMerge);
+  Node* new_loop0_loop = FindSuccessor(new_loop0_loop_entry, IrOpcode::kLoop);
+  // TODO(titzer): check the internal copies of loop1 and loop2.
+
+  Node* new_loop0_branch = FindSuccessor(new_loop0_loop, IrOpcode::kBranch);
+  Node* new_loop0_if_true = FindSuccessor(new_loop0_branch, IrOpcode::kIfTrue);
+  Node* new_loop0_exit = FindSuccessor(new_loop0_branch, IrOpcode::kIfFalse);
+
+  USE(new_loop0_if_true);
+
+  Node* new_ret = T.graph.end()->InputAt(0);
+  CHECK_EQ(IrOpcode::kReturn, new_ret->opcode());
+
+  Node* new_loop0_phi = new_ret->InputAt(0);
+  CHECK_EQ(IrOpcode::kPhi, new_loop0_phi->opcode());
+  CHECK_EQ(new_loop0_loop, NodeProperties::GetControlInput(new_loop0_phi));
+  CHECK_EQ(new_loop0_phi, FindSuccessor(new_loop0_loop, IrOpcode::kPhi));
+
+  // Check that the return returns the phi from the OSR loop and control
+  // depends on the copy of the outer loop0.
+  CheckInputs(new_ret, new_loop0_phi, T.graph.start(), new_loop0_exit);
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/test/cctest/compiler/test-pipeline.cc b/test/cctest/compiler/test-pipeline.cc
index 98b0bae..f4ffd02 100644
--- a/test/cctest/compiler/test-pipeline.cc
+++ b/test/cctest/compiler/test-pipeline.cc
@@ -2,35 +2,43 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "src/v8.h"
-#include "test/cctest/cctest.h"
-
-#include "src/ast-numbering.h"
 #include "src/compiler.h"
 #include "src/compiler/pipeline.h"
 #include "src/handles.h"
-#include "src/parser.h"
-#include "src/rewriter.h"
-#include "src/scopes.h"
+#include "src/parsing/parser.h"
+#include "test/cctest/cctest.h"
 
-using namespace v8::internal;
-using namespace v8::internal::compiler;
+namespace v8 {
+namespace internal {
+namespace compiler {
 
-TEST(PipelineAdd) {
-  InitializedHandleScope handles;
-  const char* source = "(function(a,b) { return a + b; })";
-  Handle<JSFunction> function = v8::Utils::OpenHandle(
-      *v8::Handle<v8::Function>::Cast(CompileRun(source)));
-  CompilationInfoWithZone info(function);
-
-  CHECK(Compiler::ParseAndAnalyze(&info));
+static void RunPipeline(Zone* zone, const char* source) {
+  Handle<JSFunction> function = Handle<JSFunction>::cast(v8::Utils::OpenHandle(
+      *v8::Local<v8::Function>::Cast(CompileRun(source))));
+  ParseInfo parse_info(zone, function);
+  CHECK(Compiler::ParseAndAnalyze(&parse_info));
+  CompilationInfo info(&parse_info);
+  info.SetOptimizing(BailoutId::None(), Handle<Code>(function->code()));
 
   Pipeline pipeline(&info);
-#if V8_TURBOFAN_TARGET
   Handle<Code> code = pipeline.GenerateCode();
-  CHECK(Pipeline::SupportedTarget());
   CHECK(!code.is_null());
-#else
-  USE(pipeline);
-#endif
 }
+
+
+TEST(PipelineTyped) {
+  HandleAndZoneScope handles;
+  FLAG_turbo_types = true;
+  RunPipeline(handles.main_zone(), "(function(a,b) { return a + b; })");
+}
+
+
+TEST(PipelineGeneric) {
+  HandleAndZoneScope handles;
+  FLAG_turbo_types = false;
+  RunPipeline(handles.main_zone(), "(function(a,b) { return a + b; })");
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/test/cctest/compiler/test-representation-change.cc b/test/cctest/compiler/test-representation-change.cc
index 2dc3029..7353e16 100644
--- a/test/cctest/compiler/test-representation-change.cc
+++ b/test/cctest/compiler/test-representation-change.cc
@@ -4,18 +4,15 @@
 
 #include <limits>
 
-#include "src/v8.h"
 #include "test/cctest/cctest.h"
+#include "test/cctest/compiler/codegen-tester.h"
 #include "test/cctest/compiler/graph-builder-tester.h"
 #include "test/cctest/compiler/value-helper.h"
 
 #include "src/compiler/node-matchers.h"
 #include "src/compiler/representation-change.h"
 
-using namespace v8::internal;
-using namespace v8::internal::compiler;
-
-namespace v8 {  // for friendiness.
+namespace v8 {
 namespace internal {
 namespace compiler {
 
@@ -25,8 +22,9 @@
   explicit RepresentationChangerTester(int num_parameters = 0)
       : GraphAndBuilders(main_zone()),
         javascript_(main_zone()),
-        jsgraph_(main_graph_, &main_common_, &javascript_, &main_machine_),
-        changer_(&jsgraph_, &main_simplified_, main_isolate()) {
+        jsgraph_(main_isolate(), main_graph_, &main_common_, &javascript_,
+                 &main_simplified_, &main_machine_),
+        changer_(&jsgraph_, main_isolate()) {
     Node* s = graph()->NewNode(common()->Start(num_parameters));
     graph()->SetStart(s);
   }
@@ -57,67 +55,73 @@
   void CheckFloat64Constant(Node* n, double expected) {
     Float64Matcher m(n);
     CHECK(m.HasValue());
-    CHECK_EQ(expected, m.Value());
+    CheckDoubleEq(expected, m.Value());
   }
 
   void CheckFloat32Constant(Node* n, float expected) {
     CHECK_EQ(IrOpcode::kFloat32Constant, n->opcode());
     float fval = OpParameter<float>(n->op());
-    CHECK_EQ(expected, fval);
+    CheckDoubleEq(expected, fval);
   }
 
   void CheckHeapConstant(Node* n, HeapObject* expected) {
-    HeapObjectMatcher<HeapObject> m(n);
+    HeapObjectMatcher m(n);
     CHECK(m.HasValue());
-    CHECK_EQ(expected, *m.Value().handle());
+    CHECK_EQ(expected, *m.Value());
   }
 
   void CheckNumberConstant(Node* n, double expected) {
     NumberMatcher m(n);
     CHECK_EQ(IrOpcode::kNumberConstant, n->opcode());
     CHECK(m.HasValue());
-    CHECK_EQ(expected, m.Value());
+    CheckDoubleEq(expected, m.Value());
   }
 
   Node* Parameter(int index = 0) {
-    return graph()->NewNode(common()->Parameter(index), graph()->start());
+    Node* n = graph()->NewNode(common()->Parameter(index), graph()->start());
+    NodeProperties::SetType(n, Type::Any());
+    return n;
   }
 
-  void CheckTypeError(MachineTypeUnion from, MachineTypeUnion to) {
+  void CheckTypeError(MachineRepresentation from, Type* from_type,
+                      MachineRepresentation to) {
     changer()->testing_type_errors_ = true;
     changer()->type_error_ = false;
     Node* n = Parameter(0);
-    Node* c = changer()->GetRepresentationFor(n, from, to);
+    Node* c = changer()->GetRepresentationFor(n, from, from_type, to);
     CHECK(changer()->type_error_);
     CHECK_EQ(n, c);
   }
 
-  void CheckNop(MachineTypeUnion from, MachineTypeUnion to) {
+  void CheckNop(MachineRepresentation from, Type* from_type,
+                MachineRepresentation to) {
     Node* n = Parameter(0);
-    Node* c = changer()->GetRepresentationFor(n, from, to);
+    Node* c = changer()->GetRepresentationFor(n, from, from_type, to);
     CHECK_EQ(n, c);
   }
 };
-}
-}
-}  // namespace v8::internal::compiler
 
 
-static const MachineType all_reps[] = {kRepBit,     kRepWord32,  kRepWord64,
-                                       kRepFloat32, kRepFloat64, kRepTagged};
+const MachineType kMachineTypes[] = {
+    MachineType::Float32(), MachineType::Float64(),  MachineType::Int8(),
+    MachineType::Uint8(),   MachineType::Int16(),    MachineType::Uint16(),
+    MachineType::Int32(),   MachineType::Uint32(),   MachineType::Int64(),
+    MachineType::Uint64(),  MachineType::AnyTagged()};
 
 
 TEST(BoolToBit_constant) {
   RepresentationChangerTester r;
 
   Node* true_node = r.jsgraph()->TrueConstant();
-  Node* true_bit =
-      r.changer()->GetRepresentationFor(true_node, kRepTagged, kRepBit);
+  Node* true_bit = r.changer()->GetRepresentationFor(
+      true_node, MachineRepresentation::kTagged, Type::None(),
+      MachineRepresentation::kBit);
   r.CheckInt32Constant(true_bit, 1);
 
   Node* false_node = r.jsgraph()->FalseConstant();
-  Node* false_bit =
-      r.changer()->GetRepresentationFor(false_node, kRepTagged, kRepBit);
+  Node* false_bit = r.changer()->GetRepresentationFor(
+      false_node, MachineRepresentation::kTagged, Type::None(),
+      MachineRepresentation::kBit);
   r.CheckInt32Constant(false_bit, 0);
 }
 
@@ -127,7 +131,9 @@
 
   for (int i = -5; i < 5; i++) {
     Node* node = r.jsgraph()->Int32Constant(i);
-    Node* val = r.changer()->GetRepresentationFor(node, kRepBit, kRepTagged);
+    Node* val = r.changer()->GetRepresentationFor(
+        node, MachineRepresentation::kBit, Type::Boolean(),
+        MachineRepresentation::kTagged);
     r.CheckHeapConstant(val, i == 0 ? r.isolate()->heap()->false_value()
                                     : r.isolate()->heap()->true_value());
   }
@@ -140,7 +146,9 @@
   {
     FOR_FLOAT64_INPUTS(i) {
       Node* n = r.jsgraph()->Float64Constant(*i);
-      Node* c = r.changer()->GetRepresentationFor(n, kRepFloat64, kRepTagged);
+      Node* c = r.changer()->GetRepresentationFor(
+          n, MachineRepresentation::kFloat64, Type::None(),
+          MachineRepresentation::kTagged);
       r.CheckNumberConstant(c, *i);
     }
   }
@@ -148,7 +156,9 @@
   {
     FOR_FLOAT64_INPUTS(i) {
       Node* n = r.jsgraph()->Constant(*i);
-      Node* c = r.changer()->GetRepresentationFor(n, kRepFloat64, kRepTagged);
+      Node* c = r.changer()->GetRepresentationFor(
+          n, MachineRepresentation::kFloat64, Type::None(),
+          MachineRepresentation::kTagged);
       r.CheckNumberConstant(c, *i);
     }
   }
@@ -156,7 +166,9 @@
   {
     FOR_FLOAT32_INPUTS(i) {
       Node* n = r.jsgraph()->Float32Constant(*i);
-      Node* c = r.changer()->GetRepresentationFor(n, kRepFloat32, kRepTagged);
+      Node* c = r.changer()->GetRepresentationFor(
+          n, MachineRepresentation::kFloat32, Type::None(),
+          MachineRepresentation::kTagged);
       r.CheckNumberConstant(c, *i);
     }
   }
@@ -164,8 +176,9 @@
   {
     FOR_INT32_INPUTS(i) {
       Node* n = r.jsgraph()->Int32Constant(*i);
-      Node* c = r.changer()->GetRepresentationFor(n, kRepWord32 | kTypeInt32,
-                                                  kRepTagged);
+      Node* c = r.changer()->GetRepresentationFor(
+          n, MachineRepresentation::kWord32, Type::Signed32(),
+          MachineRepresentation::kTagged);
       r.CheckNumberConstant(c, *i);
     }
   }
@@ -173,8 +186,9 @@
   {
     FOR_UINT32_INPUTS(i) {
       Node* n = r.jsgraph()->Int32Constant(*i);
-      Node* c = r.changer()->GetRepresentationFor(n, kRepWord32 | kTypeUint32,
-                                                  kRepTagged);
+      Node* c = r.changer()->GetRepresentationFor(
+          n, MachineRepresentation::kWord32, Type::Unsigned32(),
+          MachineRepresentation::kTagged);
       r.CheckNumberConstant(c, *i);
     }
   }
@@ -187,7 +201,9 @@
   {
     FOR_FLOAT64_INPUTS(i) {
       Node* n = r.jsgraph()->Float64Constant(*i);
-      Node* c = r.changer()->GetRepresentationFor(n, kRepFloat64, kRepFloat64);
+      Node* c = r.changer()->GetRepresentationFor(
+          n, MachineRepresentation::kFloat64, Type::None(),
+          MachineRepresentation::kFloat64);
       CHECK_EQ(n, c);
     }
   }
@@ -195,7 +211,9 @@
   {
     FOR_FLOAT64_INPUTS(i) {
       Node* n = r.jsgraph()->Constant(*i);
-      Node* c = r.changer()->GetRepresentationFor(n, kRepTagged, kRepFloat64);
+      Node* c = r.changer()->GetRepresentationFor(
+          n, MachineRepresentation::kTagged, Type::None(),
+          MachineRepresentation::kFloat64);
       r.CheckFloat64Constant(c, *i);
     }
   }
@@ -203,7 +221,9 @@
   {
     FOR_FLOAT32_INPUTS(i) {
       Node* n = r.jsgraph()->Float32Constant(*i);
-      Node* c = r.changer()->GetRepresentationFor(n, kRepFloat32, kRepFloat64);
+      Node* c = r.changer()->GetRepresentationFor(
+          n, MachineRepresentation::kFloat32, Type::None(),
+          MachineRepresentation::kFloat64);
       r.CheckFloat64Constant(c, *i);
     }
   }
@@ -211,8 +231,9 @@
   {
     FOR_INT32_INPUTS(i) {
       Node* n = r.jsgraph()->Int32Constant(*i);
-      Node* c = r.changer()->GetRepresentationFor(n, kRepWord32 | kTypeInt32,
-                                                  kRepFloat64);
+      Node* c = r.changer()->GetRepresentationFor(
+          n, MachineRepresentation::kWord32, Type::Signed32(),
+          MachineRepresentation::kFloat64);
       r.CheckFloat64Constant(c, *i);
     }
   }
@@ -220,8 +241,9 @@
   {
     FOR_UINT32_INPUTS(i) {
       Node* n = r.jsgraph()->Int32Constant(*i);
-      Node* c = r.changer()->GetRepresentationFor(n, kRepWord32 | kTypeUint32,
-                                                  kRepFloat64);
+      Node* c = r.changer()->GetRepresentationFor(
+          n, MachineRepresentation::kWord32, Type::Unsigned32(),
+          MachineRepresentation::kFloat64);
       r.CheckFloat64Constant(c, *i);
     }
   }
@@ -242,7 +264,9 @@
   {
     FOR_FLOAT32_INPUTS(i) {
       Node* n = r.jsgraph()->Float32Constant(*i);
-      Node* c = r.changer()->GetRepresentationFor(n, kRepFloat32, kRepFloat32);
+      Node* c = r.changer()->GetRepresentationFor(
+          n, MachineRepresentation::kFloat32, Type::None(),
+          MachineRepresentation::kFloat32);
       CHECK_EQ(n, c);
     }
   }
@@ -250,7 +274,9 @@
   {
     FOR_FLOAT32_INPUTS(i) {
       Node* n = r.jsgraph()->Constant(*i);
-      Node* c = r.changer()->GetRepresentationFor(n, kRepTagged, kRepFloat32);
+      Node* c = r.changer()->GetRepresentationFor(
+          n, MachineRepresentation::kTagged, Type::None(),
+          MachineRepresentation::kFloat32);
       r.CheckFloat32Constant(c, *i);
     }
   }
@@ -258,7 +284,9 @@
   {
     FOR_FLOAT32_INPUTS(i) {
       Node* n = r.jsgraph()->Float64Constant(*i);
-      Node* c = r.changer()->GetRepresentationFor(n, kRepFloat64, kRepFloat32);
+      Node* c = r.changer()->GetRepresentationFor(
+          n, MachineRepresentation::kFloat64, Type::None(),
+          MachineRepresentation::kFloat32);
       r.CheckFloat32Constant(c, *i);
     }
   }
@@ -267,8 +295,9 @@
     FOR_INT32_INPUTS(i) {
       if (!IsFloat32Int32(*i)) continue;
       Node* n = r.jsgraph()->Int32Constant(*i);
-      Node* c = r.changer()->GetRepresentationFor(n, kRepWord32 | kTypeInt32,
-                                                  kRepFloat32);
+      Node* c = r.changer()->GetRepresentationFor(
+          n, MachineRepresentation::kWord32, Type::Signed32(),
+          MachineRepresentation::kFloat32);
       r.CheckFloat32Constant(c, static_cast<float>(*i));
     }
   }
@@ -277,8 +306,9 @@
     FOR_UINT32_INPUTS(i) {
       if (!IsFloat32Uint32(*i)) continue;
       Node* n = r.jsgraph()->Int32Constant(*i);
-      Node* c = r.changer()->GetRepresentationFor(n, kRepWord32 | kTypeUint32,
-                                                  kRepFloat32);
+      Node* c = r.changer()->GetRepresentationFor(
+          n, MachineRepresentation::kWord32, Type::Unsigned32(),
+          MachineRepresentation::kFloat32);
       r.CheckFloat32Constant(c, static_cast<float>(*i));
     }
   }
@@ -291,8 +321,9 @@
   {
     FOR_INT32_INPUTS(i) {
       Node* n = r.jsgraph()->Int32Constant(*i);
-      Node* c = r.changer()->GetRepresentationFor(n, kRepWord32 | kTypeInt32,
-                                                  kRepWord32);
+      Node* c = r.changer()->GetRepresentationFor(
+          n, MachineRepresentation::kWord32, Type::Signed32(),
+          MachineRepresentation::kWord32);
       r.CheckInt32Constant(c, *i);
     }
   }
@@ -301,8 +332,9 @@
     FOR_INT32_INPUTS(i) {
       if (!IsFloat32Int32(*i)) continue;
       Node* n = r.jsgraph()->Float32Constant(static_cast<float>(*i));
-      Node* c = r.changer()->GetRepresentationFor(n, kRepFloat32 | kTypeInt32,
-                                                  kRepWord32);
+      Node* c = r.changer()->GetRepresentationFor(
+          n, MachineRepresentation::kFloat32, Type::Signed32(),
+          MachineRepresentation::kWord32);
       r.CheckInt32Constant(c, *i);
     }
   }
@@ -310,8 +342,9 @@
   {
     FOR_INT32_INPUTS(i) {
       Node* n = r.jsgraph()->Float64Constant(*i);
-      Node* c = r.changer()->GetRepresentationFor(n, kRepFloat64 | kTypeInt32,
-                                                  kRepWord32);
+      Node* c = r.changer()->GetRepresentationFor(
+          n, MachineRepresentation::kFloat64, Type::Signed32(),
+          MachineRepresentation::kWord32);
       r.CheckInt32Constant(c, *i);
     }
   }
@@ -319,8 +352,9 @@
   {
     FOR_INT32_INPUTS(i) {
       Node* n = r.jsgraph()->Constant(*i);
-      Node* c = r.changer()->GetRepresentationFor(n, kRepTagged | kTypeInt32,
-                                                  kRepWord32);
+      Node* c = r.changer()->GetRepresentationFor(
+          n, MachineRepresentation::kTagged, Type::Signed32(),
+          MachineRepresentation::kWord32);
       r.CheckInt32Constant(c, *i);
     }
   }
@@ -333,8 +367,9 @@
   {
     FOR_UINT32_INPUTS(i) {
       Node* n = r.jsgraph()->Int32Constant(*i);
-      Node* c = r.changer()->GetRepresentationFor(n, kRepWord32 | kTypeUint32,
-                                                  kRepWord32);
+      Node* c = r.changer()->GetRepresentationFor(
+          n, MachineRepresentation::kWord32, Type::Unsigned32(),
+          MachineRepresentation::kWord32);
       r.CheckUint32Constant(c, *i);
     }
   }
@@ -343,8 +378,9 @@
     FOR_UINT32_INPUTS(i) {
       if (!IsFloat32Uint32(*i)) continue;
       Node* n = r.jsgraph()->Float32Constant(static_cast<float>(*i));
-      Node* c = r.changer()->GetRepresentationFor(n, kRepFloat32 | kTypeUint32,
-                                                  kRepWord32);
+      Node* c = r.changer()->GetRepresentationFor(
+          n, MachineRepresentation::kFloat32, Type::Unsigned32(),
+          MachineRepresentation::kWord32);
       r.CheckUint32Constant(c, *i);
     }
   }
@@ -352,8 +388,9 @@
   {
     FOR_UINT32_INPUTS(i) {
       Node* n = r.jsgraph()->Float64Constant(*i);
-      Node* c = r.changer()->GetRepresentationFor(n, kRepFloat64 | kTypeUint32,
-                                                  kRepWord32);
+      Node* c = r.changer()->GetRepresentationFor(
+          n, MachineRepresentation::kFloat64, Type::Unsigned32(),
+          MachineRepresentation::kWord32);
       r.CheckUint32Constant(c, *i);
     }
   }
@@ -361,20 +398,21 @@
   {
     FOR_UINT32_INPUTS(i) {
       Node* n = r.jsgraph()->Constant(static_cast<double>(*i));
-      Node* c = r.changer()->GetRepresentationFor(n, kRepTagged | kTypeUint32,
-                                                  kRepWord32);
+      Node* c = r.changer()->GetRepresentationFor(
+          n, MachineRepresentation::kTagged, Type::Unsigned32(),
+          MachineRepresentation::kWord32);
       r.CheckUint32Constant(c, *i);
     }
   }
 }
 
 
-static void CheckChange(IrOpcode::Value expected, MachineTypeUnion from,
-                        MachineTypeUnion to) {
+static void CheckChange(IrOpcode::Value expected, MachineRepresentation from,
+                        Type* from_type, MachineRepresentation to) {
   RepresentationChangerTester r;
 
   Node* n = r.Parameter();
-  Node* c = r.changer()->GetRepresentationFor(n, from, to);
+  Node* c = r.changer()->GetRepresentationFor(n, from, from_type, to);
 
   CHECK_NE(c, n);
   CHECK_EQ(expected, c->opcode());
@@ -383,12 +421,13 @@
 
 
 static void CheckTwoChanges(IrOpcode::Value expected2,
-                            IrOpcode::Value expected1, MachineTypeUnion from,
-                            MachineTypeUnion to) {
+                            IrOpcode::Value expected1,
+                            MachineRepresentation from, Type* from_type,
+                            MachineRepresentation to) {
   RepresentationChangerTester r;
 
   Node* n = r.Parameter();
-  Node* c1 = r.changer()->GetRepresentationFor(n, from, to);
+  Node* c1 = r.changer()->GetRepresentationFor(n, from, from_type, to);
 
   CHECK_NE(c1, n);
   CHECK_EQ(expected1, c1->opcode());
@@ -400,70 +439,92 @@
 
 
 TEST(SingleChanges) {
-  CheckChange(IrOpcode::kChangeBoolToBit, kRepTagged, kRepBit);
-  CheckChange(IrOpcode::kChangeBitToBool, kRepBit, kRepTagged);
+  CheckChange(IrOpcode::kChangeBoolToBit, MachineRepresentation::kTagged,
+              Type::None(), MachineRepresentation::kBit);
+  CheckChange(IrOpcode::kChangeBitToBool, MachineRepresentation::kBit,
+              Type::None(), MachineRepresentation::kTagged);
 
-  CheckChange(IrOpcode::kChangeInt32ToTagged, kRepWord32 | kTypeInt32,
-              kRepTagged);
-  CheckChange(IrOpcode::kChangeUint32ToTagged, kRepWord32 | kTypeUint32,
-              kRepTagged);
-  CheckChange(IrOpcode::kChangeFloat64ToTagged, kRepFloat64, kRepTagged);
+  CheckChange(IrOpcode::kChangeInt32ToTagged, MachineRepresentation::kWord32,
+              Type::Signed32(), MachineRepresentation::kTagged);
+  CheckChange(IrOpcode::kChangeUint32ToTagged, MachineRepresentation::kWord32,
+              Type::Unsigned32(), MachineRepresentation::kTagged);
+  CheckChange(IrOpcode::kChangeFloat64ToTagged, MachineRepresentation::kFloat64,
+              Type::None(), MachineRepresentation::kTagged);
 
-  CheckChange(IrOpcode::kChangeTaggedToInt32, kRepTagged | kTypeInt32,
-              kRepWord32);
-  CheckChange(IrOpcode::kChangeTaggedToUint32, kRepTagged | kTypeUint32,
-              kRepWord32);
-  CheckChange(IrOpcode::kChangeTaggedToFloat64, kRepTagged, kRepFloat64);
+  CheckChange(IrOpcode::kChangeTaggedToInt32, MachineRepresentation::kTagged,
+              Type::Signed32(), MachineRepresentation::kWord32);
+  CheckChange(IrOpcode::kChangeTaggedToUint32, MachineRepresentation::kTagged,
+              Type::Unsigned32(), MachineRepresentation::kWord32);
+  CheckChange(IrOpcode::kChangeTaggedToFloat64, MachineRepresentation::kTagged,
+              Type::None(), MachineRepresentation::kFloat64);
 
   // Int32,Uint32 <-> Float64 are actually machine conversions.
-  CheckChange(IrOpcode::kChangeInt32ToFloat64, kRepWord32 | kTypeInt32,
-              kRepFloat64);
-  CheckChange(IrOpcode::kChangeUint32ToFloat64, kRepWord32 | kTypeUint32,
-              kRepFloat64);
-  CheckChange(IrOpcode::kChangeFloat64ToInt32, kRepFloat64 | kTypeInt32,
-              kRepWord32);
-  CheckChange(IrOpcode::kChangeFloat64ToUint32, kRepFloat64 | kTypeUint32,
-              kRepWord32);
+  CheckChange(IrOpcode::kChangeInt32ToFloat64, MachineRepresentation::kWord32,
+              Type::Signed32(), MachineRepresentation::kFloat64);
+  CheckChange(IrOpcode::kChangeUint32ToFloat64, MachineRepresentation::kWord32,
+              Type::Unsigned32(), MachineRepresentation::kFloat64);
+  CheckChange(IrOpcode::kChangeFloat64ToInt32, MachineRepresentation::kFloat64,
+              Type::Signed32(), MachineRepresentation::kWord32);
+  CheckChange(IrOpcode::kChangeFloat64ToUint32, MachineRepresentation::kFloat64,
+              Type::Unsigned32(), MachineRepresentation::kWord32);
 
-  CheckChange(IrOpcode::kTruncateFloat64ToFloat32, kRepFloat64, kRepFloat32);
+  CheckChange(IrOpcode::kTruncateFloat64ToFloat32,
+              MachineRepresentation::kFloat64, Type::None(),
+              MachineRepresentation::kFloat32);
 
   // Int32,Uint32 <-> Float32 require two changes.
   CheckTwoChanges(IrOpcode::kChangeInt32ToFloat64,
-                  IrOpcode::kTruncateFloat64ToFloat32, kRepWord32 | kTypeInt32,
-                  kRepFloat32);
+                  IrOpcode::kTruncateFloat64ToFloat32,
+                  MachineRepresentation::kWord32, Type::Signed32(),
+                  MachineRepresentation::kFloat32);
   CheckTwoChanges(IrOpcode::kChangeUint32ToFloat64,
-                  IrOpcode::kTruncateFloat64ToFloat32, kRepWord32 | kTypeUint32,
-                  kRepFloat32);
+                  IrOpcode::kTruncateFloat64ToFloat32,
+                  MachineRepresentation::kWord32, Type::Unsigned32(),
+                  MachineRepresentation::kFloat32);
   CheckTwoChanges(IrOpcode::kChangeFloat32ToFloat64,
-                  IrOpcode::kChangeFloat64ToInt32, kRepFloat32 | kTypeInt32,
-                  kRepWord32);
+                  IrOpcode::kChangeFloat64ToInt32,
+                  MachineRepresentation::kFloat32, Type::Signed32(),
+                  MachineRepresentation::kWord32);
   CheckTwoChanges(IrOpcode::kChangeFloat32ToFloat64,
-                  IrOpcode::kChangeFloat64ToUint32, kRepFloat32 | kTypeUint32,
-                  kRepWord32);
+                  IrOpcode::kChangeFloat64ToUint32,
+                  MachineRepresentation::kFloat32, Type::Unsigned32(),
+                  MachineRepresentation::kWord32);
 
   // Float32 <-> Tagged require two changes.
   CheckTwoChanges(IrOpcode::kChangeFloat32ToFloat64,
-                  IrOpcode::kChangeFloat64ToTagged, kRepFloat32, kRepTagged);
+                  IrOpcode::kChangeFloat64ToTagged,
+                  MachineRepresentation::kFloat32, Type::None(),
+                  MachineRepresentation::kTagged);
   CheckTwoChanges(IrOpcode::kChangeTaggedToFloat64,
-                  IrOpcode::kTruncateFloat64ToFloat32, kRepTagged, kRepFloat32);
+                  IrOpcode::kTruncateFloat64ToFloat32,
+                  MachineRepresentation::kTagged, Type::None(),
+                  MachineRepresentation::kFloat32);
 }
 
 
 TEST(SignednessInWord32) {
   RepresentationChangerTester r;
 
-  // TODO(titzer): assume that uses of a word32 without a sign mean kTypeInt32.
-  CheckChange(IrOpcode::kChangeTaggedToInt32, kRepTagged,
-              kRepWord32 | kTypeInt32);
-  CheckChange(IrOpcode::kChangeTaggedToUint32, kRepTagged,
-              kRepWord32 | kTypeUint32);
-  CheckChange(IrOpcode::kChangeInt32ToFloat64, kRepWord32, kRepFloat64);
-  CheckChange(IrOpcode::kChangeFloat64ToInt32, kRepFloat64, kRepWord32);
+  CheckChange(IrOpcode::kChangeTaggedToInt32, MachineRepresentation::kTagged,
+              Type::Signed32(), MachineRepresentation::kWord32);
+  CheckChange(IrOpcode::kChangeTaggedToUint32, MachineRepresentation::kTagged,
+              Type::Unsigned32(), MachineRepresentation::kWord32);
+  CheckChange(IrOpcode::kChangeInt32ToFloat64, MachineRepresentation::kWord32,
+              Type::None(), MachineRepresentation::kFloat64);
+  CheckChange(IrOpcode::kChangeFloat64ToInt32, MachineRepresentation::kFloat64,
+              Type::Signed32(), MachineRepresentation::kWord32);
+  CheckChange(IrOpcode::kTruncateFloat64ToInt32,
+              MachineRepresentation::kFloat64, Type::Number(),
+              MachineRepresentation::kWord32);
 
   CheckTwoChanges(IrOpcode::kChangeInt32ToFloat64,
-                  IrOpcode::kTruncateFloat64ToFloat32, kRepWord32, kRepFloat32);
+                  IrOpcode::kTruncateFloat64ToFloat32,
+                  MachineRepresentation::kWord32, Type::None(),
+                  MachineRepresentation::kFloat32);
   CheckTwoChanges(IrOpcode::kChangeFloat32ToFloat64,
-                  IrOpcode::kChangeFloat64ToInt32, kRepFloat32, kRepWord32);
+                  IrOpcode::kTruncateFloat64ToInt32,
+                  MachineRepresentation::kFloat32, Type::Number(),
+                  MachineRepresentation::kWord32);
 }
 
 
@@ -471,77 +532,99 @@
   RepresentationChangerTester r;
 
   // X -> X is always a nop for any single representation X.
-  for (size_t i = 0; i < arraysize(all_reps); i++) {
-    r.CheckNop(all_reps[i], all_reps[i]);
+  for (size_t i = 0; i < arraysize(kMachineTypes); i++) {
+    r.CheckNop(kMachineTypes[i].representation(), Type::None(),
+               kMachineTypes[i].representation());
   }
 
   // 32-bit floats.
-  r.CheckNop(kRepFloat32, kRepFloat32);
-  r.CheckNop(kRepFloat32 | kTypeNumber, kRepFloat32);
-  r.CheckNop(kRepFloat32, kRepFloat32 | kTypeNumber);
-
-  // 32-bit or 64-bit words can be used as branch conditions (kRepBit).
-  r.CheckNop(kRepWord32, kRepBit);
-  r.CheckNop(kRepWord32, kRepBit | kTypeBool);
-  r.CheckNop(kRepWord64, kRepBit);
-  r.CheckNop(kRepWord64, kRepBit | kTypeBool);
+  r.CheckNop(MachineRepresentation::kFloat32, Type::None(),
+             MachineRepresentation::kFloat32);
+  r.CheckNop(MachineRepresentation::kFloat32, Type::Number(),
+             MachineRepresentation::kFloat32);
 
   // 32-bit words can be used as smaller word sizes and vice versa, because
   // loads from memory implicitly sign or zero extend the value to the
   // full machine word size, and stores implicitly truncate.
-  r.CheckNop(kRepWord32, kRepWord8);
-  r.CheckNop(kRepWord32, kRepWord16);
-  r.CheckNop(kRepWord32, kRepWord32);
-  r.CheckNop(kRepWord8, kRepWord32);
-  r.CheckNop(kRepWord16, kRepWord32);
+  r.CheckNop(MachineRepresentation::kWord32, Type::Signed32(),
+             MachineRepresentation::kWord8);
+  r.CheckNop(MachineRepresentation::kWord32, Type::Signed32(),
+             MachineRepresentation::kWord16);
+  r.CheckNop(MachineRepresentation::kWord32, Type::Signed32(),
+             MachineRepresentation::kWord32);
+  r.CheckNop(MachineRepresentation::kWord8, Type::Signed32(),
+             MachineRepresentation::kWord32);
+  r.CheckNop(MachineRepresentation::kWord16, Type::Signed32(),
+             MachineRepresentation::kWord32);
 
   // kRepBit (result of comparison) is implicitly a wordish thing.
-  r.CheckNop(kRepBit, kRepWord8);
-  r.CheckNop(kRepBit | kTypeBool, kRepWord8);
-  r.CheckNop(kRepBit, kRepWord16);
-  r.CheckNop(kRepBit | kTypeBool, kRepWord16);
-  r.CheckNop(kRepBit, kRepWord32);
-  r.CheckNop(kRepBit | kTypeBool, kRepWord32);
-  r.CheckNop(kRepBit, kRepWord64);
-  r.CheckNop(kRepBit | kTypeBool, kRepWord64);
+  r.CheckNop(MachineRepresentation::kBit, Type::None(),
+             MachineRepresentation::kWord8);
+  r.CheckNop(MachineRepresentation::kBit, Type::None(),
+             MachineRepresentation::kWord16);
+  r.CheckNop(MachineRepresentation::kBit, Type::None(),
+             MachineRepresentation::kWord32);
+  r.CheckNop(MachineRepresentation::kBit, Type::None(),
+             MachineRepresentation::kWord64);
+  r.CheckNop(MachineRepresentation::kBit, Type::Boolean(),
+             MachineRepresentation::kWord8);
+  r.CheckNop(MachineRepresentation::kBit, Type::Boolean(),
+             MachineRepresentation::kWord16);
+  r.CheckNop(MachineRepresentation::kBit, Type::Boolean(),
+             MachineRepresentation::kWord32);
+  r.CheckNop(MachineRepresentation::kBit, Type::Boolean(),
+             MachineRepresentation::kWord64);
 }
 
 
 TEST(TypeErrors) {
   RepresentationChangerTester r;
 
-  // Floats cannot be implicitly converted to/from comparison conditions.
-  r.CheckTypeError(kRepFloat64, kRepBit);
-  r.CheckTypeError(kRepFloat64, kRepBit | kTypeBool);
-  r.CheckTypeError(kRepBit, kRepFloat64);
-  r.CheckTypeError(kRepBit | kTypeBool, kRepFloat64);
+  // Wordish cannot be implicitly converted to/from comparison conditions.
+  r.CheckTypeError(MachineRepresentation::kWord8, Type::None(),
+                   MachineRepresentation::kBit);
+  r.CheckTypeError(MachineRepresentation::kWord16, Type::None(),
+                   MachineRepresentation::kBit);
+  r.CheckTypeError(MachineRepresentation::kWord32, Type::None(),
+                   MachineRepresentation::kBit);
+  r.CheckTypeError(MachineRepresentation::kWord64, Type::None(),
+                   MachineRepresentation::kBit);
 
   // Floats cannot be implicitly converted to/from comparison conditions.
-  r.CheckTypeError(kRepFloat32, kRepBit);
-  r.CheckTypeError(kRepFloat32, kRepBit | kTypeBool);
-  r.CheckTypeError(kRepBit, kRepFloat32);
-  r.CheckTypeError(kRepBit | kTypeBool, kRepFloat32);
+  r.CheckTypeError(MachineRepresentation::kFloat64, Type::None(),
+                   MachineRepresentation::kBit);
+  r.CheckTypeError(MachineRepresentation::kBit, Type::None(),
+                   MachineRepresentation::kFloat64);
+  r.CheckTypeError(MachineRepresentation::kBit, Type::Boolean(),
+                   MachineRepresentation::kFloat64);
+
+  // Floats cannot be implicitly converted to/from comparison conditions.
+  r.CheckTypeError(MachineRepresentation::kFloat32, Type::None(),
+                   MachineRepresentation::kBit);
+  r.CheckTypeError(MachineRepresentation::kBit, Type::None(),
+                   MachineRepresentation::kFloat32);
+  r.CheckTypeError(MachineRepresentation::kBit, Type::Boolean(),
+                   MachineRepresentation::kFloat32);
 
   // Word64 is internal and shouldn't be implicitly converted.
-  r.CheckTypeError(kRepWord64, kRepTagged | kTypeBool);
-  r.CheckTypeError(kRepWord64, kRepTagged);
-  r.CheckTypeError(kRepWord64, kRepTagged | kTypeBool);
-  r.CheckTypeError(kRepTagged, kRepWord64);
-  r.CheckTypeError(kRepTagged | kTypeBool, kRepWord64);
+  r.CheckTypeError(MachineRepresentation::kWord64, Type::None(),
+                   MachineRepresentation::kTagged);
+  r.CheckTypeError(MachineRepresentation::kTagged, Type::None(),
+                   MachineRepresentation::kWord64);
+  r.CheckTypeError(MachineRepresentation::kTagged, Type::Boolean(),
+                   MachineRepresentation::kWord64);
 
   // Word64 / Word32 shouldn't be implicitly converted.
-  r.CheckTypeError(kRepWord64, kRepWord32);
-  r.CheckTypeError(kRepWord32, kRepWord64);
-  r.CheckTypeError(kRepWord64, kRepWord32 | kTypeInt32);
-  r.CheckTypeError(kRepWord32 | kTypeInt32, kRepWord64);
-  r.CheckTypeError(kRepWord64, kRepWord32 | kTypeUint32);
-  r.CheckTypeError(kRepWord32 | kTypeUint32, kRepWord64);
-
-  for (size_t i = 0; i < arraysize(all_reps); i++) {
-    for (size_t j = 0; j < arraysize(all_reps); j++) {
-      if (i == j) continue;
-      // Only a single from representation is allowed.
-      r.CheckTypeError(all_reps[i] | all_reps[j], kRepTagged);
-    }
-  }
+  r.CheckTypeError(MachineRepresentation::kWord64, Type::None(),
+                   MachineRepresentation::kWord32);
+  r.CheckTypeError(MachineRepresentation::kWord32, Type::None(),
+                   MachineRepresentation::kWord64);
+  r.CheckTypeError(MachineRepresentation::kWord32, Type::Signed32(),
+                   MachineRepresentation::kWord64);
+  r.CheckTypeError(MachineRepresentation::kWord32, Type::Unsigned32(),
+                   MachineRepresentation::kWord64);
 }
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/test/cctest/compiler/test-run-bytecode-graph-builder.cc b/test/cctest/compiler/test-run-bytecode-graph-builder.cc
new file mode 100644
index 0000000..88555b7
--- /dev/null
+++ b/test/cctest/compiler/test-run-bytecode-graph-builder.cc
@@ -0,0 +1,2339 @@
+// Copyright 2015 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <utility>
+
+#include "src/compiler/pipeline.h"
+#include "src/execution.h"
+#include "src/handles.h"
+#include "src/interpreter/bytecode-array-builder.h"
+#include "src/interpreter/interpreter.h"
+#include "src/parsing/parser.h"
+#include "test/cctest/cctest.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+
+static const char kFunctionName[] = "f";
+
+static const Token::Value kCompareOperators[] = {
+    Token::Value::EQ,        Token::Value::NE, Token::Value::EQ_STRICT,
+    Token::Value::NE_STRICT, Token::Value::LT, Token::Value::LTE,
+    Token::Value::GT,        Token::Value::GTE};
+
+static const int SMI_MAX = (1 << 30) - 1;
+static const int SMI_MIN = -(1 << 30);
+
+static MaybeHandle<Object> CallFunction(Isolate* isolate,
+                                        Handle<JSFunction> function) {
+  return Execution::Call(isolate, function,
+                         isolate->factory()->undefined_value(), 0, nullptr);
+}
+
+
+template <class... A>
+static MaybeHandle<Object> CallFunction(Isolate* isolate,
+                                        Handle<JSFunction> function,
+                                        A... args) {
+  Handle<Object> argv[] = {args...};
+  return Execution::Call(isolate, function,
+                         isolate->factory()->undefined_value(), sizeof...(args),
+                         argv);
+}
+
+
+template <class... A>
+class BytecodeGraphCallable {
+ public:
+  BytecodeGraphCallable(Isolate* isolate, Handle<JSFunction> function)
+      : isolate_(isolate), function_(function) {}
+  virtual ~BytecodeGraphCallable() {}
+
+  MaybeHandle<Object> operator()(A... args) {
+    return CallFunction(isolate_, function_, args...);
+  }
+
+ private:
+  Isolate* isolate_;
+  Handle<JSFunction> function_;
+};
+
+
+class BytecodeGraphTester {
+ public:
+  BytecodeGraphTester(Isolate* isolate, Zone* zone, const char* script,
+                      const char* filter = kFunctionName)
+      : isolate_(isolate), zone_(zone), script_(script) {
+    i::FLAG_ignition = true;
+    i::FLAG_always_opt = false;
+    i::FLAG_allow_natives_syntax = true;
+    i::FLAG_ignition_fallback_on_eval_and_catch = false;
+    // Set ignition filter flag via SetFlagsFromString to avoid double-free
+    // (or potential leak with StrDup() based on ownership confusion).
+    ScopedVector<char> ignition_filter(64);
+    SNPrintF(ignition_filter, "--ignition-filter=%s", filter);
+    FlagList::SetFlagsFromString(ignition_filter.start(),
+                                 ignition_filter.length());
+    // Ensure handler table is generated.
+    isolate->interpreter()->Initialize();
+  }
+  virtual ~BytecodeGraphTester() {}
+
+  template <class... A>
+  BytecodeGraphCallable<A...> GetCallable(
+      const char* functionName = kFunctionName) {
+    return BytecodeGraphCallable<A...>(isolate_, GetFunction(functionName));
+  }
+
+  Local<Message> CheckThrowsReturnMessage() {
+    TryCatch try_catch(reinterpret_cast<v8::Isolate*>(isolate_));
+    auto callable = GetCallable<>();
+    MaybeHandle<Object> no_result = callable();
+    CHECK(isolate_->has_pending_exception());
+    CHECK(try_catch.HasCaught());
+    CHECK(no_result.is_null());
+    isolate_->OptionalRescheduleException(true);
+    CHECK(!try_catch.Message().IsEmpty());
+    return try_catch.Message();
+  }
+
+  static Handle<Object> NewObject(const char* script) {
+    return v8::Utils::OpenHandle(*CompileRun(script));
+  }
+
+ private:
+  Isolate* isolate_;
+  Zone* zone_;
+  const char* script_;
+
+  Handle<JSFunction> GetFunction(const char* functionName) {
+    CompileRun(script_);
+    Local<Function> api_function = Local<Function>::Cast(
+        CcTest::global()
+            ->Get(CcTest::isolate()->GetCurrentContext(), v8_str(functionName))
+            .ToLocalChecked());
+    Handle<JSFunction> function =
+        Handle<JSFunction>::cast(v8::Utils::OpenHandle(*api_function));
+    CHECK(function->shared()->HasBytecodeArray());
+
+    ParseInfo parse_info(zone_, function);
+
+    CompilationInfo compilation_info(&parse_info);
+    compilation_info.SetOptimizing(BailoutId::None(), Handle<Code>());
+    compilation_info.MarkAsDeoptimizationEnabled();
+    // TODO(mythria): Remove this step once parse_info is not needed.
+    CHECK(Compiler::ParseAndAnalyze(&parse_info));
+    compiler::Pipeline pipeline(&compilation_info);
+    Handle<Code> code = pipeline.GenerateCode();
+    function->ReplaceCode(*code);
+
+    return function;
+  }
+
+  DISALLOW_COPY_AND_ASSIGN(BytecodeGraphTester);
+};
+
+
+#define SPACE()
+
+#define REPEAT_2(SEP, ...) __VA_ARGS__ SEP() __VA_ARGS__
+#define REPEAT_4(SEP, ...) \
+  REPEAT_2(SEP, __VA_ARGS__) SEP() REPEAT_2(SEP, __VA_ARGS__)
+#define REPEAT_8(SEP, ...) \
+  REPEAT_4(SEP, __VA_ARGS__) SEP() REPEAT_4(SEP, __VA_ARGS__)
+#define REPEAT_16(SEP, ...) \
+  REPEAT_8(SEP, __VA_ARGS__) SEP() REPEAT_8(SEP, __VA_ARGS__)
+#define REPEAT_32(SEP, ...) \
+  REPEAT_16(SEP, __VA_ARGS__) SEP() REPEAT_16(SEP, __VA_ARGS__)
+#define REPEAT_64(SEP, ...) \
+  REPEAT_32(SEP, __VA_ARGS__) SEP() REPEAT_32(SEP, __VA_ARGS__)
+#define REPEAT_128(SEP, ...) \
+  REPEAT_64(SEP, __VA_ARGS__) SEP() REPEAT_64(SEP, __VA_ARGS__)
+#define REPEAT_256(SEP, ...) \
+  REPEAT_128(SEP, __VA_ARGS__) SEP() REPEAT_128(SEP, __VA_ARGS__)
+
+#define REPEAT_127(SEP, ...)  \
+  REPEAT_64(SEP, __VA_ARGS__) \
+  SEP()                       \
+  REPEAT_32(SEP, __VA_ARGS__) \
+  SEP()                       \
+  REPEAT_16(SEP, __VA_ARGS__) \
+  SEP()                       \
+  REPEAT_8(SEP, __VA_ARGS__)  \
+  SEP()                       \
+  REPEAT_4(SEP, __VA_ARGS__) SEP() REPEAT_2(SEP, __VA_ARGS__) SEP() __VA_ARGS__
+
+
+template <int N, typename T = Handle<Object>>
+struct ExpectedSnippet {
+  const char* code_snippet;
+  T return_value_and_parameters[N + 1];
+
+  inline T return_value() const { return return_value_and_parameters[0]; }
+
+  inline T parameter(int i) const {
+    CHECK_GE(i, 0);
+    CHECK_LT(i, N);
+    return return_value_and_parameters[1 + i];
+  }
+};
+
+
+TEST(BytecodeGraphBuilderReturnStatements) {
+  HandleAndZoneScope scope;
+  Isolate* isolate = scope.main_isolate();
+  Zone* zone = scope.main_zone();
+  Factory* factory = isolate->factory();
+
+  ExpectedSnippet<0> snippets[] = {
+      {"return;", {factory->undefined_value()}},
+      {"return null;", {factory->null_value()}},
+      {"return true;", {factory->true_value()}},
+      {"return false;", {factory->false_value()}},
+      {"return 0;", {factory->NewNumberFromInt(0)}},
+      {"return +1;", {factory->NewNumberFromInt(1)}},
+      {"return -1;", {factory->NewNumberFromInt(-1)}},
+      {"return +127;", {factory->NewNumberFromInt(127)}},
+      {"return -128;", {factory->NewNumberFromInt(-128)}},
+      {"return 0.001;", {factory->NewNumber(0.001)}},
+      {"return 3.7e-60;", {factory->NewNumber(3.7e-60)}},
+      {"return -3.7e60;", {factory->NewNumber(-3.7e60)}},
+      {"return '';", {factory->NewStringFromStaticChars("")}},
+      {"return 'catfood';", {factory->NewStringFromStaticChars("catfood")}},
+      {"return NaN;", {factory->nan_value()}}};
+
+  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
+  for (size_t i = 0; i < num_snippets; i++) {
+    ScopedVector<char> script(1024);
+    SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName,
+             snippets[i].code_snippet, kFunctionName);
+
+    BytecodeGraphTester tester(isolate, zone, script.start());
+    auto callable = tester.GetCallable<>();
+    Handle<Object> return_value = callable().ToHandleChecked();
+    CHECK(return_value->SameValue(*snippets[i].return_value()));
+  }
+}
+
+
+TEST(BytecodeGraphBuilderPrimitiveExpressions) {
+  HandleAndZoneScope scope;
+  Isolate* isolate = scope.main_isolate();
+  Zone* zone = scope.main_zone();
+  Factory* factory = isolate->factory();
+
+  ExpectedSnippet<0> snippets[] = {
+      {"return 1 + 1;", {factory->NewNumberFromInt(2)}},
+      {"return 20 - 30;", {factory->NewNumberFromInt(-10)}},
+      {"return 4 * 100;", {factory->NewNumberFromInt(400)}},
+      {"return 100 / 5;", {factory->NewNumberFromInt(20)}},
+      {"return 25 % 7;", {factory->NewNumberFromInt(4)}},
+  };
+
+  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
+  for (size_t i = 0; i < num_snippets; i++) {
+    ScopedVector<char> script(1024);
+    SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName,
+             snippets[i].code_snippet, kFunctionName);
+
+    BytecodeGraphTester tester(isolate, zone, script.start());
+    auto callable = tester.GetCallable<>();
+    Handle<Object> return_value = callable().ToHandleChecked();
+    CHECK(return_value->SameValue(*snippets[i].return_value()));
+  }
+}
+
+
+TEST(BytecodeGraphBuilderTwoParameterTests) {
+  HandleAndZoneScope scope;
+  Isolate* isolate = scope.main_isolate();
+  Zone* zone = scope.main_zone();
+  Factory* factory = isolate->factory();
+
+  ExpectedSnippet<2> snippets[] = {
+      // Integers
+      {"return p1 + p2;",
+       {factory->NewNumberFromInt(-70), factory->NewNumberFromInt(3),
+        factory->NewNumberFromInt(-73)}},
+      {"return p1 + p2 + 3;",
+       {factory->NewNumberFromInt(1139044), factory->NewNumberFromInt(300),
+        factory->NewNumberFromInt(1138741)}},
+      {"return p1 - p2;",
+       {factory->NewNumberFromInt(1100), factory->NewNumberFromInt(1000),
+        factory->NewNumberFromInt(-100)}},
+      {"return p1 * p2;",
+       {factory->NewNumberFromInt(-100000), factory->NewNumberFromInt(1000),
+        factory->NewNumberFromInt(-100)}},
+      {"return p1 / p2;",
+       {factory->NewNumberFromInt(-10), factory->NewNumberFromInt(1000),
+        factory->NewNumberFromInt(-100)}},
+      {"return p1 % p2;",
+       {factory->NewNumberFromInt(5), factory->NewNumberFromInt(373),
+        factory->NewNumberFromInt(16)}},
+      // Doubles
+      {"return p1 + p2;",
+       {factory->NewHeapNumber(9.999), factory->NewHeapNumber(3.333),
+        factory->NewHeapNumber(6.666)}},
+      {"return p1 - p2;",
+       {factory->NewHeapNumber(-3.333), factory->NewHeapNumber(3.333),
+        factory->NewHeapNumber(6.666)}},
+      {"return p1 * p2;",
+       {factory->NewHeapNumber(3.333 * 6.666), factory->NewHeapNumber(3.333),
+        factory->NewHeapNumber(6.666)}},
+      {"return p1 / p2;",
+       {factory->NewHeapNumber(2.25), factory->NewHeapNumber(9),
+        factory->NewHeapNumber(4)}},
+      // Strings
+      {"return p1 + p2;",
+       {factory->NewStringFromStaticChars("abcdef"),
+        factory->NewStringFromStaticChars("abc"),
+        factory->NewStringFromStaticChars("def")}}};
+
+  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
+  for (size_t i = 0; i < num_snippets; i++) {
+    ScopedVector<char> script(1024);
+    SNPrintF(script, "function %s(p1, p2) { %s }\n%s(0, 0);", kFunctionName,
+             snippets[i].code_snippet, kFunctionName);
+
+    BytecodeGraphTester tester(isolate, zone, script.start());
+    auto callable = tester.GetCallable<Handle<Object>, Handle<Object>>();
+    Handle<Object> return_value =
+        callable(snippets[i].parameter(0), snippets[i].parameter(1))
+            .ToHandleChecked();
+    CHECK(return_value->SameValue(*snippets[i].return_value()));
+  }
+}
+
+
+TEST(BytecodeGraphBuilderNamedLoad) {
+  HandleAndZoneScope scope;
+  Isolate* isolate = scope.main_isolate();
+  Zone* zone = scope.main_zone();
+  Factory* factory = isolate->factory();
+
+  ExpectedSnippet<1> snippets[] = {
+      {"return p1.val;",
+       {factory->NewNumberFromInt(10),
+        BytecodeGraphTester::NewObject("({val : 10})")}},
+      {"return p1[\"name\"];",
+       {factory->NewStringFromStaticChars("abc"),
+        BytecodeGraphTester::NewObject("({name : 'abc'})")}},
+      {"'use strict'; return p1.val;",
+       {factory->NewNumberFromInt(10),
+        BytecodeGraphTester::NewObject("({val : 10 })")}},
+      {"'use strict'; return p1[\"val\"];",
+       {factory->NewNumberFromInt(10),
+        BytecodeGraphTester::NewObject("({val : 10, name : 'abc'})")}},
+      {"var b;\n" REPEAT_127(SPACE, " b = p1.name; ") " return p1.name;\n",
+       {factory->NewStringFromStaticChars("abc"),
+        BytecodeGraphTester::NewObject("({name : 'abc'})")}},
+      {"'use strict'; var b;\n"
+       REPEAT_127(SPACE, " b = p1.name; ")
+       "return p1.name;\n",
+       {factory->NewStringFromStaticChars("abc"),
+        BytecodeGraphTester::NewObject("({ name : 'abc'})")}},
+  };
+
+  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
+  for (size_t i = 0; i < num_snippets; i++) {
+    ScopedVector<char> script(2048);
+    SNPrintF(script, "function %s(p1) { %s };\n%s(0);", kFunctionName,
+             snippets[i].code_snippet, kFunctionName);
+
+    BytecodeGraphTester tester(isolate, zone, script.start());
+    auto callable = tester.GetCallable<Handle<Object>>();
+    Handle<Object> return_value =
+        callable(snippets[i].parameter(0)).ToHandleChecked();
+    CHECK(return_value->SameValue(*snippets[i].return_value()));
+  }
+}
+
+
+TEST(BytecodeGraphBuilderKeyedLoad) {
+  HandleAndZoneScope scope;
+  Isolate* isolate = scope.main_isolate();
+  Zone* zone = scope.main_zone();
+  Factory* factory = isolate->factory();
+
+  ExpectedSnippet<2> snippets[] = {
+      {"return p1[p2];",
+       {factory->NewNumberFromInt(10),
+        BytecodeGraphTester::NewObject("({val : 10})"),
+        factory->NewStringFromStaticChars("val")}},
+      {"return p1[100];",
+       {factory->NewStringFromStaticChars("abc"),
+        BytecodeGraphTester::NewObject("({100 : 'abc'})"),
+        factory->NewNumberFromInt(0)}},
+      {"var b = 100; return p1[b];",
+       {factory->NewStringFromStaticChars("abc"),
+        BytecodeGraphTester::NewObject("({100 : 'abc'})"),
+        factory->NewNumberFromInt(0)}},
+      {"'use strict'; return p1[p2];",
+       {factory->NewNumberFromInt(10),
+        BytecodeGraphTester::NewObject("({val : 10 })"),
+        factory->NewStringFromStaticChars("val")}},
+      {"'use strict'; return p1[100];",
+       {factory->NewNumberFromInt(10),
+        BytecodeGraphTester::NewObject("({100 : 10})"),
+        factory->NewNumberFromInt(0)}},
+      {"'use strict'; var b = p2; return p1[b];",
+       {factory->NewStringFromStaticChars("abc"),
+        BytecodeGraphTester::NewObject("({100 : 'abc'})"),
+        factory->NewNumberFromInt(100)}},
+      {"var b;\n" REPEAT_127(SPACE, " b = p1[p2]; ") " return p1[p2];\n",
+       {factory->NewStringFromStaticChars("abc"),
+        BytecodeGraphTester::NewObject("({100 : 'abc'})"),
+        factory->NewNumberFromInt(100)}},
+      {"'use strict'; var b;\n" REPEAT_127(SPACE,
+                                           " b = p1[p2]; ") "return p1[p2];\n",
+       {factory->NewStringFromStaticChars("abc"),
+        BytecodeGraphTester::NewObject("({ 100 : 'abc'})"),
+        factory->NewNumberFromInt(100)}},
+  };
+
+  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
+  for (size_t i = 0; i < num_snippets; i++) {
+    ScopedVector<char> script(2048);
+    SNPrintF(script, "function %s(p1, p2) { %s };\n%s(0);", kFunctionName,
+             snippets[i].code_snippet, kFunctionName);
+
+    BytecodeGraphTester tester(isolate, zone, script.start());
+    auto callable = tester.GetCallable<Handle<Object>, Handle<Object>>();
+    Handle<Object> return_value =
+        callable(snippets[i].parameter(0), snippets[i].parameter(1))
+            .ToHandleChecked();
+    CHECK(return_value->SameValue(*snippets[i].return_value()));
+  }
+}
+
+
+TEST(BytecodeGraphBuilderNamedStore) {
+  HandleAndZoneScope scope;
+  Isolate* isolate = scope.main_isolate();
+  Zone* zone = scope.main_zone();
+  Factory* factory = isolate->factory();
+
+  ExpectedSnippet<1> snippets[] = {
+      {"return p1.val = 20;",
+       {factory->NewNumberFromInt(20),
+        BytecodeGraphTester::NewObject("({val : 10})")}},
+      {"p1.type = 'int'; return p1.type;",
+       {factory->NewStringFromStaticChars("int"),
+        BytecodeGraphTester::NewObject("({val : 10})")}},
+      {"p1.name = 'def'; return p1[\"name\"];",
+       {factory->NewStringFromStaticChars("def"),
+        BytecodeGraphTester::NewObject("({name : 'abc'})")}},
+      {"'use strict'; p1.val = 20; return p1.val;",
+       {factory->NewNumberFromInt(20),
+        BytecodeGraphTester::NewObject("({val : 10 })")}},
+      {"'use strict'; return p1.type = 'int';",
+       {factory->NewStringFromStaticChars("int"),
+        BytecodeGraphTester::NewObject("({val : 10})")}},
+      {"'use strict'; p1.val = 20; return p1[\"val\"];",
+       {factory->NewNumberFromInt(20),
+        BytecodeGraphTester::NewObject("({val : 10, name : 'abc'})")}},
+      {"var b = 'abc';\n" REPEAT_127(
+           SPACE, " p1.name = b; ") " p1.name = 'def'; return p1.name;\n",
+       {factory->NewStringFromStaticChars("def"),
+        BytecodeGraphTester::NewObject("({name : 'abc'})")}},
+      {"'use strict'; var b = 'def';\n" REPEAT_127(
+           SPACE, " p1.name = 'abc'; ") "p1.name = b; return p1.name;\n",
+       {factory->NewStringFromStaticChars("def"),
+        BytecodeGraphTester::NewObject("({ name : 'abc'})")}},
+  };
+
+  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
+  for (size_t i = 0; i < num_snippets; i++) {
+    ScopedVector<char> script(3072);
+    SNPrintF(script, "function %s(p1) { %s };\n%s({});", kFunctionName,
+             snippets[i].code_snippet, kFunctionName);
+
+    BytecodeGraphTester tester(isolate, zone, script.start());
+    auto callable = tester.GetCallable<Handle<Object>>();
+    Handle<Object> return_value =
+        callable(snippets[i].parameter(0)).ToHandleChecked();
+    CHECK(return_value->SameValue(*snippets[i].return_value()));
+  }
+}
+
+
+TEST(BytecodeGraphBuilderKeyedStore) {
+  HandleAndZoneScope scope;
+  Isolate* isolate = scope.main_isolate();
+  Zone* zone = scope.main_zone();
+  Factory* factory = isolate->factory();
+
+  ExpectedSnippet<2> snippets[] = {
+      {"p1[p2] = 20; return p1[p2];",
+       {factory->NewNumberFromInt(20),
+        BytecodeGraphTester::NewObject("({val : 10})"),
+        factory->NewStringFromStaticChars("val")}},
+      {"return p1[100] = 'def';",
+       {factory->NewStringFromStaticChars("def"),
+        BytecodeGraphTester::NewObject("({100 : 'abc'})"),
+        factory->NewNumberFromInt(0)}},
+      {"var b = 100; p1[b] = 'def'; return p1[b];",
+       {factory->NewStringFromStaticChars("def"),
+        BytecodeGraphTester::NewObject("({100 : 'abc'})"),
+        factory->NewNumberFromInt(0)}},
+      {"'use strict'; p1[p2] = 20; return p1[p2];",
+       {factory->NewNumberFromInt(20),
+        BytecodeGraphTester::NewObject("({val : 10 })"),
+        factory->NewStringFromStaticChars("val")}},
+      {"'use strict'; return p1[100] = 20;",
+       {factory->NewNumberFromInt(20),
+        BytecodeGraphTester::NewObject("({100 : 10})"),
+        factory->NewNumberFromInt(0)}},
+      {"'use strict'; var b = p2; p1[b] = 'def'; return p1[b];",
+       {factory->NewStringFromStaticChars("def"),
+        BytecodeGraphTester::NewObject("({100 : 'abc'})"),
+        factory->NewNumberFromInt(100)}},
+      {"var b;\n" REPEAT_127(
+           SPACE, " b = p1[p2]; ") " p1[p2] = 'def'; return p1[p2];\n",
+       {factory->NewStringFromStaticChars("def"),
+        BytecodeGraphTester::NewObject("({100 : 'abc'})"),
+        factory->NewNumberFromInt(100)}},
+      {"'use strict'; var b;\n" REPEAT_127(
+           SPACE, " b = p1[p2]; ") " p1[p2] = 'def'; return p1[p2];\n",
+       {factory->NewStringFromStaticChars("def"),
+        BytecodeGraphTester::NewObject("({ 100 : 'abc'})"),
+        factory->NewNumberFromInt(100)}},
+  };
+
+  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
+  for (size_t i = 0; i < num_snippets; i++) {
+    ScopedVector<char> script(2048);
+    SNPrintF(script, "function %s(p1, p2) { %s };\n%s({});", kFunctionName,
+             snippets[i].code_snippet, kFunctionName);
+
+    BytecodeGraphTester tester(isolate, zone, script.start());
+    auto callable = tester.GetCallable<Handle<Object>>();
+    Handle<Object> return_value =
+        callable(snippets[i].parameter(0)).ToHandleChecked();
+    CHECK(return_value->SameValue(*snippets[i].return_value()));
+  }
+}
+
+
+TEST(BytecodeGraphBuilderPropertyCall) {
+  HandleAndZoneScope scope;
+  Isolate* isolate = scope.main_isolate();
+  Zone* zone = scope.main_zone();
+  Factory* factory = isolate->factory();
+
+  ExpectedSnippet<1> snippets[] = {
+      {"return p1.func();",
+       {factory->NewNumberFromInt(25),
+        BytecodeGraphTester::NewObject("({func() { return 25; }})")}},
+      {"return p1.func('abc');",
+       {factory->NewStringFromStaticChars("abc"),
+        BytecodeGraphTester::NewObject("({func(a) { return a; }})")}},
+      {"return p1.func(1, 2, 3, 4, 5, 6, 7, 8);",
+       {factory->NewNumberFromInt(36),
+        BytecodeGraphTester::NewObject(
+            "({func(a, b, c, d, e, f, g, h) {\n"
+            "  return a + b + c + d + e + f + g + h;}})")}},
+  };
+
+  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
+  for (size_t i = 0; i < num_snippets; i++) {
+    ScopedVector<char> script(2048);
+    SNPrintF(script, "function %s(p1) { %s };\n%s({func() {}});", kFunctionName,
+             snippets[i].code_snippet, kFunctionName);
+
+    BytecodeGraphTester tester(isolate, zone, script.start());
+    auto callable = tester.GetCallable<Handle<Object>>();
+    Handle<Object> return_value =
+        callable(snippets[i].parameter(0)).ToHandleChecked();
+    CHECK(return_value->SameValue(*snippets[i].return_value()));
+  }
+}
+
+
+TEST(BytecodeGraphBuilderCallNew) {
+  HandleAndZoneScope scope;
+  Isolate* isolate = scope.main_isolate();
+  Zone* zone = scope.main_zone();
+  Factory* factory = isolate->factory();
+
+  ExpectedSnippet<0> snippets[] = {
+      {"function counter() { this.count = 20; }\n"
+       "function f() {\n"
+       "  var c = new counter();\n"
+       "  return c.count;\n"
+       "}; f()",
+       {factory->NewNumberFromInt(20)}},
+      {"function counter(arg0) { this.count = 17; this.x = arg0; }\n"
+       "function f() {\n"
+       "  var c = new counter(6);\n"
+       "  return c.count + c.x;\n"
+       "}; f()",
+       {factory->NewNumberFromInt(23)}},
+      {"function counter(arg0, arg1) {\n"
+       "  this.count = 17; this.x = arg0; this.y = arg1;\n"
+       "}\n"
+       "function f() {\n"
+       "  var c = new counter(3, 5);\n"
+       "  return c.count + c.x + c.y;\n"
+       "}; f()",
+       {factory->NewNumberFromInt(25)}},
+  };
+
+  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
+  for (size_t i = 0; i < num_snippets; i++) {
+    BytecodeGraphTester tester(isolate, zone, snippets[i].code_snippet);
+    auto callable = tester.GetCallable<>();
+    Handle<Object> return_value = callable().ToHandleChecked();
+    CHECK(return_value->SameValue(*snippets[i].return_value()));
+  }
+}
+
+
+TEST(BytecodeGraphBuilderCreateClosure) {
+  HandleAndZoneScope scope;
+  Isolate* isolate = scope.main_isolate();
+  Zone* zone = scope.main_zone();
+  Factory* factory = isolate->factory();
+
+  ExpectedSnippet<0> snippets[] = {
+      {"function f() {\n"
+       "  function counter() { this.count = 20; }\n"
+       "  var c = new counter();\n"
+       "  return c.count;\n"
+       "}; f()",
+       {factory->NewNumberFromInt(20)}},
+      {"function f() {\n"
+       "  function counter(arg0) { this.count = 17; this.x = arg0; }\n"
+       "  var c = new counter(6);\n"
+       "  return c.count + c.x;\n"
+       "}; f()",
+       {factory->NewNumberFromInt(23)}},
+      {"function f() {\n"
+       "  function counter(arg0, arg1) {\n"
+       "    this.count = 17; this.x = arg0; this.y = arg1;\n"
+       "  }\n"
+       "  var c = new counter(3, 5);\n"
+       "  return c.count + c.x + c.y;\n"
+       "}; f()",
+       {factory->NewNumberFromInt(25)}},
+  };
+
+  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
+  for (size_t i = 0; i < num_snippets; i++) {
+    BytecodeGraphTester tester(isolate, zone, snippets[i].code_snippet);
+    auto callable = tester.GetCallable<>();
+    Handle<Object> return_value = callable().ToHandleChecked();
+    CHECK(return_value->SameValue(*snippets[i].return_value()));
+  }
+}
+
+
+TEST(BytecodeGraphBuilderCallRuntime) {
+  HandleAndZoneScope scope;
+  Isolate* isolate = scope.main_isolate();
+  Zone* zone = scope.main_zone();
+  Factory* factory = isolate->factory();
+
+  ExpectedSnippet<1> snippets[] = {
+      {"function f(arg0) { return %MaxSmi(); }\nf()",
+       {factory->NewNumberFromInt(Smi::kMaxValue), factory->undefined_value()}},
+      {"function f(arg0) { return %IsArray(arg0) }\nf(undefined)",
+       {factory->true_value(), BytecodeGraphTester::NewObject("[1, 2, 3]")}},
+      {"function f(arg0) { return %Add(arg0, 2) }\nf(1)",
+       {factory->NewNumberFromInt(5), factory->NewNumberFromInt(3)}},
+      {"function f(arg0) { return %spread_arguments(arg0).length }\nf([])",
+       {factory->NewNumberFromInt(3),
+        BytecodeGraphTester::NewObject("[1, 2, 3]")}},
+  };
+
+  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
+  for (size_t i = 0; i < num_snippets; i++) {
+    BytecodeGraphTester tester(isolate, zone, snippets[i].code_snippet);
+    auto callable = tester.GetCallable<Handle<Object>>();
+    Handle<Object> return_value =
+        callable(snippets[i].parameter(0)).ToHandleChecked();
+    CHECK(return_value->SameValue(*snippets[i].return_value()));
+  }
+}
+
+
+TEST(BytecodeGraphBuilderGlobals) {
+  HandleAndZoneScope scope;
+  Isolate* isolate = scope.main_isolate();
+  Zone* zone = scope.main_zone();
+  Factory* factory = isolate->factory();
+
+  ExpectedSnippet<0> snippets[] = {
+      {"var global = 321;\n function f() { return global; };\n f();",
+       {factory->NewNumberFromInt(321)}},
+      {"var global = 321;\n"
+       "function f() { global = 123; return global };\n f();",
+       {factory->NewNumberFromInt(123)}},
+      {"var global = function() { return 'abc'};\n"
+       "function f() { return global(); };\n f();",
+       {factory->NewStringFromStaticChars("abc")}},
+      {"var global = 456;\n"
+       "function f() { 'use strict'; return global; };\n f();",
+       {factory->NewNumberFromInt(456)}},
+      {"var global = 987;\n"
+       "function f() { 'use strict'; global = 789; return global };\n f();",
+       {factory->NewNumberFromInt(789)}},
+      {"var global = function() { return 'xyz'};\n"
+       "function f() { 'use strict'; return global(); };\n f();",
+       {factory->NewStringFromStaticChars("xyz")}},
+      {"var global = 'abc'; var global_obj = {val:123};\n"
+       "function f() {\n" REPEAT_127(
+           SPACE, " var b = global_obj.name;\n") "return global; };\n f();\n",
+       {factory->NewStringFromStaticChars("abc")}},
+      {"var global = 'abc'; var global_obj = {val:123};\n"
+       "function f() { 'use strict';\n" REPEAT_127(
+           SPACE, " var b = global_obj.name;\n") "global = 'xyz'; return "
+                                                 "global };\n f();\n",
+       {factory->NewStringFromStaticChars("xyz")}},
+      {"function f() { return typeof(undeclared_var); }\n; f();\n",
+       {factory->NewStringFromStaticChars("undefined")}},
+      {"var defined_var = 10; function f() { return typeof(defined_var); }\n; "
+       "f();\n",
+       {factory->NewStringFromStaticChars("number")}},
+  };
+
+  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
+  for (size_t i = 0; i < num_snippets; i++) {
+    BytecodeGraphTester tester(isolate, zone, snippets[i].code_snippet);
+    auto callable = tester.GetCallable<>();
+    Handle<Object> return_value = callable().ToHandleChecked();
+    CHECK(return_value->SameValue(*snippets[i].return_value()));
+  }
+}
+
+
+TEST(BytecodeGraphBuilderToObject) {
+  // TODO(mythria): tests for ToObject. Needs ForIn.
+}
+
+
+TEST(BytecodeGraphBuilderToName) {
+  HandleAndZoneScope scope;
+  Isolate* isolate = scope.main_isolate();
+  Zone* zone = scope.main_zone();
+  Factory* factory = isolate->factory();
+
+  ExpectedSnippet<0> snippets[] = {
+      {"var a = 'val'; var obj = {[a] : 10}; return obj.val;",
+       {factory->NewNumberFromInt(10)}},
+      {"var a = 20; var obj = {[a] : 10}; return obj['20'];",
+       {factory->NewNumberFromInt(10)}},
+      {"var a = 20; var obj = {[a] : 10}; return obj[20];",
+       {factory->NewNumberFromInt(10)}},
+      {"var a = {val:23}; var obj = {[a] : 10}; return obj[a];",
+       {factory->NewNumberFromInt(10)}},
+      {"var a = {val:23}; var obj = {[a] : 10}; return obj['[object Object]'];",
+       {factory->NewNumberFromInt(10)}},
+      {"var a = {toString : function() { return 'x'}};\n"
+       "var obj = {[a] : 10};\n"
+       "return obj.x;",
+       {factory->NewNumberFromInt(10)}},
+      {"var a = {valueOf : function() { return 'x'}};\n"
+       "var obj = {[a] : 10};\n"
+       "return obj.x;",
+       {factory->undefined_value()}},
+      {"var a = {[Symbol.toPrimitive] : function() { return 'x'}};\n"
+       "var obj = {[a] : 10};\n"
+       "return obj.x;",
+       {factory->NewNumberFromInt(10)}},
+  };
+
+  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
+  for (size_t i = 0; i < num_snippets; i++) {
+    ScopedVector<char> script(1024);
+    SNPrintF(script, "function %s() { %s }\n%s({});", kFunctionName,
+             snippets[i].code_snippet, kFunctionName);
+
+    BytecodeGraphTester tester(isolate, zone, script.start());
+    auto callable = tester.GetCallable<>();
+    Handle<Object> return_value = callable().ToHandleChecked();
+    CHECK(return_value->SameValue(*snippets[i].return_value()));
+  }
+}
+
+
+TEST(BytecodeGraphBuilderLogicalNot) {
+  HandleAndZoneScope scope;
+  Isolate* isolate = scope.main_isolate();
+  Zone* zone = scope.main_zone();
+  Factory* factory = isolate->factory();
+
+  ExpectedSnippet<1> snippets[] = {
+      {"return !p1;",
+       {factory->false_value(),
+        BytecodeGraphTester::NewObject("({val : 10})")}},
+      {"return !p1;", {factory->true_value(), factory->NewNumberFromInt(0)}},
+      {"return !p1;", {factory->true_value(), factory->undefined_value()}},
+      {"return !p1;", {factory->false_value(), factory->NewNumberFromInt(10)}},
+      {"return !p1;", {factory->false_value(), factory->true_value()}},
+      {"return !p1;",
+       {factory->false_value(), factory->NewStringFromStaticChars("abc")}},
+  };
+
+  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
+  for (size_t i = 0; i < num_snippets; i++) {
+    ScopedVector<char> script(1024);
+    SNPrintF(script, "function %s(p1) { %s }\n%s({});", kFunctionName,
+             snippets[i].code_snippet, kFunctionName);
+
+    BytecodeGraphTester tester(isolate, zone, script.start());
+    auto callable = tester.GetCallable<Handle<Object>>();
+    Handle<Object> return_value =
+        callable(snippets[i].parameter(0)).ToHandleChecked();
+    CHECK(return_value->SameValue(*snippets[i].return_value()));
+  }
+}
+
+
+TEST(BytecodeGraphBuilderTypeOf) {
+  HandleAndZoneScope scope;
+  Isolate* isolate = scope.main_isolate();
+  Zone* zone = scope.main_zone();
+  Factory* factory = isolate->factory();
+
+  ExpectedSnippet<1> snippets[] = {
+      {"return typeof p1;",
+       {factory->NewStringFromStaticChars("object"),
+        BytecodeGraphTester::NewObject("({val : 10})")}},
+      {"return typeof p1;",
+       {factory->NewStringFromStaticChars("undefined"),
+        factory->undefined_value()}},
+      {"return typeof p1;",
+       {factory->NewStringFromStaticChars("number"),
+        factory->NewNumberFromInt(10)}},
+      {"return typeof p1;",
+       {factory->NewStringFromStaticChars("boolean"), factory->true_value()}},
+      {"return typeof p1;",
+       {factory->NewStringFromStaticChars("string"),
+        factory->NewStringFromStaticChars("abc")}},
+  };
+
+  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
+  for (size_t i = 0; i < num_snippets; i++) {
+    ScopedVector<char> script(1024);
+    SNPrintF(script, "function %s(p1) { %s }\n%s({});", kFunctionName,
+             snippets[i].code_snippet, kFunctionName);
+
+    BytecodeGraphTester tester(isolate, zone, script.start());
+    auto callable = tester.GetCallable<Handle<Object>>();
+    Handle<Object> return_value =
+        callable(snippets[i].parameter(0)).ToHandleChecked();
+    CHECK(return_value->SameValue(*snippets[i].return_value()));
+  }
+}
+
+
+TEST(BytecodeGraphBuilderCountOperation) {
+  HandleAndZoneScope scope;
+  Isolate* isolate = scope.main_isolate();
+  Zone* zone = scope.main_zone();
+  Factory* factory = isolate->factory();
+
+  ExpectedSnippet<1> snippets[] = {
+      {"return ++p1;",
+       {factory->NewNumberFromInt(11), factory->NewNumberFromInt(10)}},
+      {"return p1++;",
+       {factory->NewNumberFromInt(10), factory->NewNumberFromInt(10)}},
+      {"return p1++ + 10;",
+       {factory->NewHeapNumber(15.23), factory->NewHeapNumber(5.23)}},
+      {"return 20 + ++p1;",
+       {factory->NewHeapNumber(27.23), factory->NewHeapNumber(6.23)}},
+      {"return --p1;",
+       {factory->NewHeapNumber(9.8), factory->NewHeapNumber(10.8)}},
+      {"return p1--;",
+       {factory->NewHeapNumber(10.8), factory->NewHeapNumber(10.8)}},
+      {"return p1-- + 10;",
+       {factory->NewNumberFromInt(20), factory->NewNumberFromInt(10)}},
+      {"return 20 + --p1;",
+       {factory->NewNumberFromInt(29), factory->NewNumberFromInt(10)}},
+      {"return p1.val--;",
+       {factory->NewNumberFromInt(10),
+        BytecodeGraphTester::NewObject("({val : 10})")}},
+      {"return ++p1['val'];",
+       {factory->NewNumberFromInt(11),
+        BytecodeGraphTester::NewObject("({val : 10})")}},
+      {"return ++p1[1];",
+       {factory->NewNumberFromInt(11),
+        BytecodeGraphTester::NewObject("({1 : 10})")}},
+      {" function inner() { return p1 } return --p1;",
+       {factory->NewNumberFromInt(9), factory->NewNumberFromInt(10)}},
+      {" function inner() { return p1 } return p1--;",
+       {factory->NewNumberFromInt(10), factory->NewNumberFromInt(10)}},
+      {"return ++p1;",
+       {factory->nan_value(), factory->NewStringFromStaticChars("String")}},
+  };
+
+  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
+  for (size_t i = 0; i < num_snippets; i++) {
+    ScopedVector<char> script(1024);
+    SNPrintF(script, "function %s(p1) { %s }\n%s({});", kFunctionName,
+             snippets[i].code_snippet, kFunctionName);
+
+    BytecodeGraphTester tester(isolate, zone, script.start());
+    auto callable = tester.GetCallable<Handle<Object>>();
+    Handle<Object> return_value =
+        callable(snippets[i].parameter(0)).ToHandleChecked();
+    CHECK(return_value->SameValue(*snippets[i].return_value()));
+  }
+}
+
+
+TEST(BytecodeGraphBuilderDelete) {
+  HandleAndZoneScope scope;
+  Isolate* isolate = scope.main_isolate();
+  Zone* zone = scope.main_zone();
+  Factory* factory = isolate->factory();
+
+  ExpectedSnippet<1> snippets[] = {
+      {"return delete p1.val;",
+       {factory->true_value(), BytecodeGraphTester::NewObject("({val : 10})")}},
+      {"delete p1.val; return p1.val;",
+       {factory->undefined_value(),
+        BytecodeGraphTester::NewObject("({val : 10})")}},
+      {"delete p1.name; return p1.val;",
+       {factory->NewNumberFromInt(10),
+        BytecodeGraphTester::NewObject("({val : 10, name:'abc'})")}},
+      {"'use strict'; return delete p1.val;",
+       {factory->true_value(), BytecodeGraphTester::NewObject("({val : 10})")}},
+      {"'use strict'; delete p1.val; return p1.val;",
+       {factory->undefined_value(),
+        BytecodeGraphTester::NewObject("({val : 10})")}},
+      {"'use strict'; delete p1.name; return p1.val;",
+       {factory->NewNumberFromInt(10),
+        BytecodeGraphTester::NewObject("({val : 10, name:'abc'})")}},
+  };
+
+  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
+  for (size_t i = 0; i < num_snippets; i++) {
+    ScopedVector<char> script(1024);
+    SNPrintF(script, "function %s(p1) { %s }\n%s({});", kFunctionName,
+             snippets[i].code_snippet, kFunctionName);
+
+    BytecodeGraphTester tester(isolate, zone, script.start());
+    auto callable = tester.GetCallable<Handle<Object>>();
+    Handle<Object> return_value =
+        callable(snippets[i].parameter(0)).ToHandleChecked();
+    CHECK(return_value->SameValue(*snippets[i].return_value()));
+  }
+}
+
+
+TEST(BytecodeGraphBuilderDeleteGlobal) {
+  HandleAndZoneScope scope;
+  Isolate* isolate = scope.main_isolate();
+  Zone* zone = scope.main_zone();
+  Factory* factory = isolate->factory();
+
+  ExpectedSnippet<0> snippets[] = {
+      {"var obj = {val : 10, type : 'int'};"
+       "function f() {return delete obj;};",
+       {factory->false_value()}},
+      {"function f() {return delete this;};", {factory->true_value()}},
+      {"var obj = {val : 10, type : 'int'};"
+       "function f() {return delete obj.val;};",
+       {factory->true_value()}},
+      {"var obj = {val : 10, type : 'int'};"
+       "function f() {'use strict'; return delete obj.val;};",
+       {factory->true_value()}},
+      {"var obj = {val : 10, type : 'int'};"
+       "function f() {delete obj.val; return obj.val;};",
+       {factory->undefined_value()}},
+      {"var obj = {val : 10, type : 'int'};"
+       "function f() {'use strict'; delete obj.val; return obj.val;};",
+       {factory->undefined_value()}},
+      {"var obj = {1 : 10, 2 : 20};"
+       "function f() { return delete obj[1]; };",
+       {factory->true_value()}},
+      {"var obj = {1 : 10, 2 : 20};"
+       "function f() { 'use strict';  return delete obj[1];};",
+       {factory->true_value()}},
+      {"obj = {1 : 10, 2 : 20};"
+       "function f() { delete obj[1]; return obj[2];};",
+       {factory->NewNumberFromInt(20)}},
+      {"function f() {"
+       "  var obj = {1 : 10, 2 : 20};"
+       "  function inner() { return obj[1]; };"
+       "  return delete obj[1];"
+       "}",
+       {factory->true_value()}},
+  };
+
+  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
+  for (size_t i = 0; i < num_snippets; i++) {
+    ScopedVector<char> script(1024);
+    SNPrintF(script, "%s %s({});", snippets[i].code_snippet, kFunctionName);
+
+    BytecodeGraphTester tester(isolate, zone, script.start());
+    auto callable = tester.GetCallable<>();
+    Handle<Object> return_value = callable().ToHandleChecked();
+    CHECK(return_value->SameValue(*snippets[i].return_value()));
+  }
+}
+
+
+TEST(BytecodeGraphBuilderDeleteLookupSlot) {
+  HandleAndZoneScope scope;
+  Isolate* isolate = scope.main_isolate();
+  Zone* zone = scope.main_zone();
+  Factory* factory = isolate->factory();
+
+  // TODO(mythria): Add more tests when we have support for LdaLookupSlot.
+  const char* function_prologue = "var f;"
+                                  "var x = 1;"
+                                  "y = 10;"
+                                  "var obj = {val:10};"
+                                  "var z = 30;"
+                                  "function f1() {"
+                                  "  var z = 20;"
+                                  "  eval(\"function t() {";
+  const char* function_epilogue = "        }; f = t; t();\");"
+                                  "}"
+                                  "f1();";
+
+  ExpectedSnippet<0> snippets[] = {
+      {"return delete y;", {factory->true_value()}},
+      {"return delete z;", {factory->false_value()}},
+  };
+
+  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
+  for (size_t i = 0; i < num_snippets; i++) {
+    ScopedVector<char> script(1024);
+    SNPrintF(script, "%s %s %s", function_prologue, snippets[i].code_snippet,
+             function_epilogue);
+
+    BytecodeGraphTester tester(isolate, zone, script.start(), "t");
+    auto callable = tester.GetCallable<>();
+    Handle<Object> return_value = callable().ToHandleChecked();
+    CHECK(return_value->SameValue(*snippets[i].return_value()));
+  }
+}
+
+
+TEST(BytecodeGraphBuilderLookupSlot) {
+  HandleAndZoneScope scope;
+  Isolate* isolate = scope.main_isolate();
+  Zone* zone = scope.main_zone();
+  Factory* factory = isolate->factory();
+
+  const char* function_prologue = "var f;"
+                                  "var x = 12;"
+                                  "y = 10;"
+                                  "var obj = {val:3.1414};"
+                                  "var z = 30;"
+                                  "function f1() {"
+                                  "  var z = 20;"
+                                  "  eval(\"function t() {";
+  const char* function_epilogue = "        }; f = t; t();\");"
+                                  "}"
+                                  "f1();";
+
+  ExpectedSnippet<0> snippets[] = {
+      {"return x;", {factory->NewNumber(12)}},
+      {"return obj.val;", {factory->NewNumber(3.1414)}},
+      {"return typeof x;", {factory->NewStringFromStaticChars("number")}},
+      {"return typeof dummy;",
+       {factory->NewStringFromStaticChars("undefined")}},
+      {"x = 23; return x;", {factory->NewNumber(23)}},
+      {"'use strict'; obj.val = 23.456; return obj.val;",
+       {factory->NewNumber(23.456)}}};
+
+  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
+  for (size_t i = 0; i < num_snippets; i++) {
+    ScopedVector<char> script(1024);
+    SNPrintF(script, "%s %s %s", function_prologue, snippets[i].code_snippet,
+             function_epilogue);
+
+    BytecodeGraphTester tester(isolate, zone, script.start(), "t");
+    auto callable = tester.GetCallable<>();
+    Handle<Object> return_value = callable().ToHandleChecked();
+    CHECK(return_value->SameValue(*snippets[i].return_value()));
+  }
+}
+
+
+TEST(BytecodeGraphBuilderLookupSlotWide) {
+  HandleAndZoneScope scope;
+  Isolate* isolate = scope.main_isolate();
+  Zone* zone = scope.main_zone();
+  Factory* factory = isolate->factory();
+
+  const char* function_prologue =
+      "var f;"
+      "var x = 12;"
+      "y = 10;"
+      "var obj = {val:3.1414};"
+      "var z = 30;"
+      "function f1() {"
+      "  var z = 20;"
+      "  eval(\"function t() {";
+  const char* function_epilogue =
+      "        }; f = t; t();\");"
+      "}"
+      "f1();";
+
+  ExpectedSnippet<0> snippets[] = {
+      {"var y = 2.3;" REPEAT_256(SPACE, "y = 2.3;") "return x;",
+       {factory->NewNumber(12)}},
+      {"var y = 2.3;" REPEAT_256(SPACE, "y = 2.3;") "return typeof x;",
+       {factory->NewStringFromStaticChars("number")}},
+      {"var y = 2.3;" REPEAT_256(SPACE, "y = 2.3;") "return x = 23;",
+       {factory->NewNumber(23)}},
+      {"'use strict';" REPEAT_256(SPACE, "y = 2.3;") "return obj.val = 23.456;",
+       {factory->NewNumber(23.456)}}};
+
+  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
+  for (size_t i = 0; i < num_snippets; i++) {
+    ScopedVector<char> script(3072);
+    SNPrintF(script, "%s %s %s", function_prologue, snippets[i].code_snippet,
+             function_epilogue);
+
+    BytecodeGraphTester tester(isolate, zone, script.start(), "t");
+    auto callable = tester.GetCallable<>();
+    Handle<Object> return_value = callable().ToHandleChecked();
+    CHECK(return_value->SameValue(*snippets[i].return_value()));
+  }
+}
+
+
+TEST(BytecodeGraphBuilderCallLookupSlot) {
+  HandleAndZoneScope scope;
+  Isolate* isolate = scope.main_isolate();
+  Zone* zone = scope.main_zone();
+
+  ExpectedSnippet<0> snippets[] = {
+      {"g = function(){ return 2 }; eval(''); return g();",
+       {handle(Smi::FromInt(2), isolate)}},
+      {"g = function(){ return 2 }; eval('g = function() {return 3}');\n"
+       "return g();",
+       {handle(Smi::FromInt(3), isolate)}},
+      {"g = { x: function(){ return this.y }, y: 20 };\n"
+       "eval('g = { x: g.x, y: 30 }');\n"
+       "return g.x();",
+       {handle(Smi::FromInt(30), isolate)}},
+  };
+
+  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
+  for (size_t i = 0; i < num_snippets; i++) {
+    ScopedVector<char> script(1024);
+    SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName,
+             snippets[i].code_snippet, kFunctionName);
+    BytecodeGraphTester tester(isolate, zone, script.start());
+    auto callable = tester.GetCallable<>();
+    Handle<Object> return_value = callable().ToHandleChecked();
+    CHECK(return_value->SameValue(*snippets[i].return_value()));
+  }
+}
+
+
+TEST(BytecodeGraphBuilderEval) {
+  HandleAndZoneScope scope;
+  Isolate* isolate = scope.main_isolate();
+  Zone* zone = scope.main_zone();
+  Factory* factory = isolate->factory();
+
+  ExpectedSnippet<0> snippets[] = {
+      {"return eval('1;');", {handle(Smi::FromInt(1), isolate)}},
+      {"return eval('100 * 20;');", {handle(Smi::FromInt(2000), isolate)}},
+      {"var x = 10; return eval('x + 20;');",
+       {handle(Smi::FromInt(30), isolate)}},
+      {"var x = 10; eval('x = 33;'); return x;",
+       {handle(Smi::FromInt(33), isolate)}},
+      {"'use strict'; var x = 20; var z = 0;\n"
+       "eval('var x = 33; z = x;'); return x + z;",
+       {handle(Smi::FromInt(53), isolate)}},
+      {"eval('var x = 33;'); eval('var y = x + 20'); return x + y;",
+       {handle(Smi::FromInt(86), isolate)}},
+      {"var x = 1; eval('for(i = 0; i < 10; i++) x = x + 1;'); return x",
+       {handle(Smi::FromInt(11), isolate)}},
+      {"var x = 10; eval('var x = 20;'); return x;",
+       {handle(Smi::FromInt(20), isolate)}},
+      {"var x = 1; eval('\"use strict\"; var x = 2;'); return x;",
+       {handle(Smi::FromInt(1), isolate)}},
+      {"'use strict'; var x = 1; eval('var x = 2;'); return x;",
+       {handle(Smi::FromInt(1), isolate)}},
+      {"var x = 10; eval('x + 20;'); return typeof x;",
+       {factory->NewStringFromStaticChars("number")}},
+      {"eval('var y = 10;'); return typeof unallocated;",
+       {factory->NewStringFromStaticChars("undefined")}},
+      {"'use strict'; eval('var y = 10;'); return typeof unallocated;",
+       {factory->NewStringFromStaticChars("undefined")}},
+      {"eval('var x = 10;'); return typeof x;",
+       {factory->NewStringFromStaticChars("number")}},
+      {"var x = {}; eval('var x = 10;'); return typeof x;",
+       {factory->NewStringFromStaticChars("number")}},
+      {"'use strict'; var x = {}; eval('var x = 10;'); return typeof x;",
+       {factory->NewStringFromStaticChars("object")}},
+  };
+
+  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
+  for (size_t i = 0; i < num_snippets; i++) {
+    ScopedVector<char> script(1024);
+    SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName,
+             snippets[i].code_snippet, kFunctionName);
+    BytecodeGraphTester tester(isolate, zone, script.start());
+    auto callable = tester.GetCallable<>();
+    Handle<Object> return_value = callable().ToHandleChecked();
+    CHECK(return_value->SameValue(*snippets[i].return_value()));
+  }
+}
+
+
+TEST(BytecodeGraphBuilderEvalParams) {
+  HandleAndZoneScope scope;
+  Isolate* isolate = scope.main_isolate();
+  Zone* zone = scope.main_zone();
+
+  ExpectedSnippet<1> snippets[] = {
+      {"var x = 10; return eval('x + p1;');",
+       {handle(Smi::FromInt(30), isolate), handle(Smi::FromInt(20), isolate)}},
+      {"var x = 10; eval('p1 = x;'); return p1;",
+       {handle(Smi::FromInt(10), isolate), handle(Smi::FromInt(20), isolate)}},
+      {"var a = 10;"
+       "function inner() { return eval('a + p1;');}"
+       "return inner();",
+       {handle(Smi::FromInt(30), isolate), handle(Smi::FromInt(20), isolate)}},
+  };
+
+  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
+  for (size_t i = 0; i < num_snippets; i++) {
+    ScopedVector<char> script(1024);
+    SNPrintF(script, "function %s(p1) { %s }\n%s(0);", kFunctionName,
+             snippets[i].code_snippet, kFunctionName);
+    BytecodeGraphTester tester(isolate, zone, script.start());
+    auto callable = tester.GetCallable<Handle<Object>>();
+    Handle<Object> return_value =
+        callable(snippets[i].parameter(0)).ToHandleChecked();
+    CHECK(return_value->SameValue(*snippets[i].return_value()));
+  }
+}
+
+
+TEST(BytecodeGraphBuilderEvalGlobal) {
+  HandleAndZoneScope scope;
+  Isolate* isolate = scope.main_isolate();
+  Zone* zone = scope.main_zone();
+  Factory* factory = isolate->factory();
+
+  ExpectedSnippet<0> snippets[] = {
+      {"function add_global() { eval('function f() { z = 33; }; f()'); };"
+       "function f() { add_global(); return z; }; f();",
+       {handle(Smi::FromInt(33), isolate)}},
+      {"function add_global() {\n"
+       " eval('\"use strict\"; function f() { y = 33; };"
+       "      try { f() } catch(e) {}');\n"
+       "}\n"
+       "function f() { add_global(); return typeof y; } f();",
+       {factory->NewStringFromStaticChars("undefined")}},
+  };
+
+  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
+  for (size_t i = 0; i < num_snippets; i++) {
+    BytecodeGraphTester tester(isolate, zone, snippets[i].code_snippet);
+    auto callable = tester.GetCallable<>();
+    Handle<Object> return_value = callable().ToHandleChecked();
+    CHECK(return_value->SameValue(*snippets[i].return_value()));
+  }
+}
+
+
+bool get_compare_result(Token::Value opcode, Handle<Object> lhs_value,
+                        Handle<Object> rhs_value) {
+  switch (opcode) {
+    case Token::Value::EQ:
+      return Object::Equals(lhs_value, rhs_value).FromJust();
+    case Token::Value::NE:
+      return !Object::Equals(lhs_value, rhs_value).FromJust();
+    case Token::Value::EQ_STRICT:
+      return lhs_value->StrictEquals(*rhs_value);
+    case Token::Value::NE_STRICT:
+      return !lhs_value->StrictEquals(*rhs_value);
+    case Token::Value::LT:
+      return Object::LessThan(lhs_value, rhs_value).FromJust();
+    case Token::Value::LTE:
+      return Object::LessThanOrEqual(lhs_value, rhs_value).FromJust();
+    case Token::Value::GT:
+      return Object::GreaterThan(lhs_value, rhs_value).FromJust();
+    case Token::Value::GTE:
+      return Object::GreaterThanOrEqual(lhs_value, rhs_value).FromJust();
+    default:
+      UNREACHABLE();
+      return false;
+  }
+}
+
+
+const char* get_code_snippet(Token::Value opcode) {
+  switch (opcode) {
+    case Token::Value::EQ:
+      return "return p1 == p2;";
+    case Token::Value::NE:
+      return "return p1 != p2;";
+    case Token::Value::EQ_STRICT:
+      return "return p1 === p2;";
+    case Token::Value::NE_STRICT:
+      return "return p1 !== p2;";
+    case Token::Value::LT:
+      return "return p1 < p2;";
+    case Token::Value::LTE:
+      return "return p1 <= p2;";
+    case Token::Value::GT:
+      return "return p1 > p2;";
+    case Token::Value::GTE:
+      return "return p1 >= p2;";
+    default:
+      UNREACHABLE();
+      return "";
+  }
+}
+
+
+TEST(BytecodeGraphBuilderCompare) {
+  HandleAndZoneScope scope;
+  Isolate* isolate = scope.main_isolate();
+  Zone* zone = scope.main_zone();
+  Factory* factory = isolate->factory();
+  Handle<Object> lhs_values[] = {
+      factory->NewNumberFromInt(10), factory->NewHeapNumber(3.45),
+      factory->NewStringFromStaticChars("abc"),
+      factory->NewNumberFromInt(SMI_MAX), factory->NewNumberFromInt(SMI_MIN)};
+  Handle<Object> rhs_values[] = {factory->NewNumberFromInt(10),
+                                 factory->NewStringFromStaticChars("10"),
+                                 factory->NewNumberFromInt(20),
+                                 factory->NewStringFromStaticChars("abc"),
+                                 factory->NewHeapNumber(3.45),
+                                 factory->NewNumberFromInt(SMI_MAX),
+                                 factory->NewNumberFromInt(SMI_MIN)};
+
+  for (size_t i = 0; i < arraysize(kCompareOperators); i++) {
+    ScopedVector<char> script(1024);
+    SNPrintF(script, "function %s(p1, p2) { %s }\n%s({}, {});", kFunctionName,
+             get_code_snippet(kCompareOperators[i]), kFunctionName);
+
+    BytecodeGraphTester tester(isolate, zone, script.start());
+    auto callable = tester.GetCallable<Handle<Object>, Handle<Object>>();
+    for (size_t j = 0; j < arraysize(lhs_values); j++) {
+      for (size_t k = 0; k < arraysize(rhs_values); k++) {
+        Handle<Object> return_value =
+            callable(lhs_values[j], rhs_values[k]).ToHandleChecked();
+        bool result = get_compare_result(kCompareOperators[i], lhs_values[j],
+                                         rhs_values[k]);
+        CHECK(return_value->SameValue(*factory->ToBoolean(result)));
+      }
+    }
+  }
+}
+
+
+TEST(BytecodeGraphBuilderTestIn) {
+  HandleAndZoneScope scope;
+  Isolate* isolate = scope.main_isolate();
+  Zone* zone = scope.main_zone();
+  Factory* factory = isolate->factory();
+
+  ExpectedSnippet<2> snippets[] = {
+      {"return p2 in p1;",
+       {factory->true_value(), BytecodeGraphTester::NewObject("({val : 10})"),
+        factory->NewStringFromStaticChars("val")}},
+      {"return p2 in p1;",
+       {factory->true_value(), BytecodeGraphTester::NewObject("[]"),
+        factory->NewStringFromStaticChars("length")}},
+      {"return p2 in p1;",
+       {factory->true_value(), BytecodeGraphTester::NewObject("[]"),
+        factory->NewStringFromStaticChars("toString")}},
+      {"return p2 in p1;",
+       {factory->true_value(), BytecodeGraphTester::NewObject("({val : 10})"),
+        factory->NewStringFromStaticChars("toString")}},
+      {"return p2 in p1;",
+       {factory->false_value(), BytecodeGraphTester::NewObject("({val : 10})"),
+        factory->NewStringFromStaticChars("abc")}},
+      {"return p2 in p1;",
+       {factory->false_value(), BytecodeGraphTester::NewObject("({val : 10})"),
+        factory->NewNumberFromInt(10)}},
+      {"return p2 in p1;",
+       {factory->true_value(), BytecodeGraphTester::NewObject("({10 : 'val'})"),
+        factory->NewNumberFromInt(10)}},
+      {"return p2 in p1;",
+       {factory->false_value(),
+        BytecodeGraphTester::NewObject("({10 : 'val'})"),
+        factory->NewNumberFromInt(1)}},
+  };
+
+  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
+  for (size_t i = 0; i < num_snippets; i++) {
+    ScopedVector<char> script(1024);
+    SNPrintF(script, "function %s(p1, p2) { %s }\n%s({}, {});", kFunctionName,
+             snippets[i].code_snippet, kFunctionName);
+
+    BytecodeGraphTester tester(isolate, zone, script.start());
+    auto callable = tester.GetCallable<Handle<Object>, Handle<Object>>();
+    Handle<Object> return_value =
+        callable(snippets[i].parameter(0), snippets[i].parameter(1))
+            .ToHandleChecked();
+    CHECK(return_value->SameValue(*snippets[i].return_value()));
+  }
+}
+
+
+TEST(BytecodeGraphBuilderTestInstanceOf) {
+  HandleAndZoneScope scope;
+  Isolate* isolate = scope.main_isolate();
+  Zone* zone = scope.main_zone();
+  Factory* factory = isolate->factory();
+
+  ExpectedSnippet<1> snippets[] = {
+      {"return p1 instanceof Object;",
+       {factory->true_value(), BytecodeGraphTester::NewObject("({val : 10})")}},
+      {"return p1 instanceof String;",
+       {factory->false_value(), factory->NewStringFromStaticChars("string")}},
+      {"var cons = function() {};"
+       "var obj = new cons();"
+       "return obj instanceof cons;",
+       {factory->true_value(), factory->undefined_value()}},
+  };
+
+  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
+  for (size_t i = 0; i < num_snippets; i++) {
+    ScopedVector<char> script(1024);
+    SNPrintF(script, "function %s(p1) { %s }\n%s({});", kFunctionName,
+             snippets[i].code_snippet, kFunctionName);
+
+    BytecodeGraphTester tester(isolate, zone, script.start());
+    auto callable = tester.GetCallable<Handle<Object>>();
+    Handle<Object> return_value =
+        callable(snippets[i].parameter(0)).ToHandleChecked();
+    CHECK(return_value->SameValue(*snippets[i].return_value()));
+  }
+}
+
+
+TEST(BytecodeGraphBuilderThrow) {
+  HandleAndZoneScope scope;
+  Isolate* isolate = scope.main_isolate();
+  Zone* zone = scope.main_zone();
+
+  // TODO(mythria): Add more tests when real try-catch and deoptimization
+  // information are supported.
+  ExpectedSnippet<0, const char*> snippets[] = {
+      {"throw undefined;", {"Uncaught undefined"}},
+      {"throw 1;", {"Uncaught 1"}},
+      {"throw 'Error';", {"Uncaught Error"}},
+      {"throw 'Error1'; throw 'Error2'", {"Uncaught Error1"}},
+      // TODO(mythria): Enable these tests when JumpIfTrue is supported.
+      // {"var a = true; if (a) { throw 'Error'; }", {"Error"}},
+  };
+
+  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
+  for (size_t i = 0; i < num_snippets; i++) {
+    ScopedVector<char> script(1024);
+    SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName,
+             snippets[i].code_snippet, kFunctionName);
+    BytecodeGraphTester tester(isolate, zone, script.start());
+    v8::Local<v8::String> message = tester.CheckThrowsReturnMessage()->Get();
+    v8::Local<v8::String> expected_string = v8_str(snippets[i].return_value());
+    CHECK(
+        message->Equals(CcTest::isolate()->GetCurrentContext(), expected_string)
+            .FromJust());
+  }
+}
+
+
+TEST(BytecodeGraphBuilderContext) {
+  HandleAndZoneScope scope;
+  Isolate* isolate = scope.main_isolate();
+  Zone* zone = scope.main_zone();
+  Factory* factory = isolate->factory();
+
+  ExpectedSnippet<0> snippets[] = {
+      {"var x = 'outer';"
+       "function f() {"
+       " 'use strict';"
+       " {"
+       "   let x = 'inner';"
+       "   (function() {x});"
+       " }"
+       "return(x);"
+       "}"
+       "f();",
+       {factory->NewStringFromStaticChars("outer")}},
+      {"var x = 'outer';"
+       "function f() {"
+       " 'use strict';"
+       " {"
+       "   let x = 'inner ';"
+       "   var innerFunc = function() {return x};"
+       " }"
+       "return(innerFunc() + x);"
+       "}"
+       "f();",
+       {factory->NewStringFromStaticChars("inner outer")}},
+      {"var x = 'outer';"
+       "function f() {"
+       " 'use strict';"
+       " {"
+       "   let x = 'inner ';"
+       "   var innerFunc = function() {return x;};"
+       "   {"
+       "     let x = 'innermost ';"
+       "     var innerMostFunc = function() {return x + innerFunc();};"
+       "   }"
+       "   x = 'inner_changed ';"
+       " }"
+       " return(innerMostFunc() + x);"
+       "}"
+       "f();",
+       {factory->NewStringFromStaticChars("innermost inner_changed outer")}},
+  };
+
+  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
+  for (size_t i = 0; i < num_snippets; i++) {
+    ScopedVector<char> script(1024);
+    SNPrintF(script, "%s", snippets[i].code_snippet);
+
+    BytecodeGraphTester tester(isolate, zone, script.start(), "f");
+    auto callable = tester.GetCallable<>("f");
+    Handle<Object> return_value = callable().ToHandleChecked();
+    CHECK(return_value->SameValue(*snippets[i].return_value()));
+  }
+}
+
+
+TEST(BytecodeGraphBuilderLoadContext) {
+  HandleAndZoneScope scope;
+  Isolate* isolate = scope.main_isolate();
+  Zone* zone = scope.main_zone();
+  Factory* factory = isolate->factory();
+
+  ExpectedSnippet<1> snippets[] = {
+      {"function Outer() {"
+       "  var outerVar = 2;"
+       "  function Inner(innerArg) {"
+       "    this.innerFunc = function () {"
+       "     return outerVar * innerArg;"
+       "    };"
+       "  };"
+       "  this.getInnerFunc = function GetInner() {"
+       "     return new Inner(3).innerFunc;"
+       "   }"
+       "}"
+       "var f = new Outer().getInnerFunc();"
+       "f();",
+       {factory->NewNumberFromInt(6), factory->undefined_value()}},
+      {"function Outer() {"
+       "  var outerVar = 2;"
+       "  function Inner(innerArg) {"
+       "    this.innerFunc = function () {"
+       "     outerVar = innerArg; return outerVar;"
+       "    };"
+       "  };"
+       "  this.getInnerFunc = function GetInner() {"
+       "     return new Inner(10).innerFunc;"
+       "   }"
+       "}"
+       "var f = new Outer().getInnerFunc();"
+       "f();",
+       {factory->NewNumberFromInt(10), factory->undefined_value()}},
+      {"function testOuter(outerArg) {"
+       " this.testinnerFunc = function testInner(innerArg) {"
+       "   return innerArg + outerArg;"
+       " }"
+       "}"
+       "var f = new testOuter(10).testinnerFunc;"
+       "f(0);",
+       {factory->NewNumberFromInt(14), factory->NewNumberFromInt(4)}},
+      {"function testOuter(outerArg) {"
+       " var outerVar = outerArg * 2;"
+       " this.testinnerFunc = function testInner(innerArg) {"
+       "   outerVar = outerVar + innerArg; return outerVar;"
+       " }"
+       "}"
+       "var f = new testOuter(10).testinnerFunc;"
+       "f(0);",
+       {factory->NewNumberFromInt(24), factory->NewNumberFromInt(4)}}};
+
+  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
+  for (size_t i = 0; i < num_snippets; i++) {
+    ScopedVector<char> script(1024);
+    SNPrintF(script, "%s", snippets[i].code_snippet);
+
+    BytecodeGraphTester tester(isolate, zone, script.start(), "*");
+    auto callable = tester.GetCallable<Handle<Object>>("f");
+    Handle<Object> return_value =
+        callable(snippets[i].parameter(0)).ToHandleChecked();
+    CHECK(return_value->SameValue(*snippets[i].return_value()));
+  }
+}
+
+
+TEST(BytecodeGraphBuilderCreateArgumentsNoParameters) {
+  HandleAndZoneScope scope;
+  Isolate* isolate = scope.main_isolate();
+  Zone* zone = scope.main_zone();
+  Factory* factory = isolate->factory();
+
+  ExpectedSnippet<0> snippets[] = {
+      {"function f() {return arguments[0];}", {factory->undefined_value()}},
+      {"function f(a) {return arguments[0];}", {factory->undefined_value()}},
+      {"function f() {'use strict'; return arguments[0];}",
+       {factory->undefined_value()}},
+      {"function f(a) {'use strict'; return arguments[0];}",
+       {factory->undefined_value()}},
+  };
+
+  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
+  for (size_t i = 0; i < num_snippets; i++) {
+    ScopedVector<char> script(1024);
+    SNPrintF(script, "%s\n%s();", snippets[i].code_snippet, kFunctionName);
+
+    BytecodeGraphTester tester(isolate, zone, script.start());
+    auto callable = tester.GetCallable<>();
+    Handle<Object> return_value = callable().ToHandleChecked();
+    CHECK(return_value->SameValue(*snippets[i].return_value()));
+  }
+}
+
+
+TEST(BytecodeGraphBuilderCreateArguments) {
+  HandleAndZoneScope scope;
+  Isolate* isolate = scope.main_isolate();
+  Zone* zone = scope.main_zone();
+  Factory* factory = isolate->factory();
+
+  ExpectedSnippet<3> snippets[] = {
+      {"function f(a, b, c) {return arguments[0];}",
+       {factory->NewNumberFromInt(1), factory->NewNumberFromInt(1),
+        factory->NewNumberFromInt(2), factory->NewNumberFromInt(3)}},
+      {"function f(a, b, c) {return arguments[3];}",
+       {factory->undefined_value(), factory->NewNumberFromInt(1),
+        factory->NewNumberFromInt(2), factory->NewNumberFromInt(3)}},
+      {"function f(a, b, c) { b = c; return arguments[1];}",
+       {factory->NewNumberFromInt(3), factory->NewNumberFromInt(1),
+        factory->NewNumberFromInt(2), factory->NewNumberFromInt(3)}},
+      {"function f(a, b, c) {'use strict'; return arguments[0];}",
+       {factory->NewNumberFromInt(1), factory->NewNumberFromInt(1),
+        factory->NewNumberFromInt(2), factory->NewNumberFromInt(3)}},
+      {"function f(a, b, c) {'use strict'; return arguments[3];}",
+       {factory->undefined_value(), factory->NewNumberFromInt(1),
+        factory->NewNumberFromInt(2), factory->NewNumberFromInt(3)}},
+      {"function f(a, b, c) {'use strict'; b = c; return arguments[1];}",
+       {factory->NewNumberFromInt(2), factory->NewNumberFromInt(1),
+        factory->NewNumberFromInt(2), factory->NewNumberFromInt(3)}},
+      {"function inline_func(a, b) { return arguments[0] }"
+       "function f(a, b, c) {return inline_func(b, c) + arguments[0];}",
+       {factory->NewNumberFromInt(3), factory->NewNumberFromInt(1),
+        factory->NewNumberFromInt(2), factory->NewNumberFromInt(30)}},
+  };
+
+  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
+  for (size_t i = 0; i < num_snippets; i++) {
+    ScopedVector<char> script(1024);
+    SNPrintF(script, "%s\n%s();", snippets[i].code_snippet, kFunctionName);
+
+    BytecodeGraphTester tester(isolate, zone, script.start());
+    auto callable =
+        tester.GetCallable<Handle<Object>, Handle<Object>, Handle<Object>>();
+    Handle<Object> return_value =
+        callable(snippets[i].parameter(0), snippets[i].parameter(1),
+                 snippets[i].parameter(2))
+            .ToHandleChecked();
+    CHECK(return_value->SameValue(*snippets[i].return_value()));
+  }
+}
+
+
+TEST(BytecodeGraphBuilderRegExpLiterals) {
+  HandleAndZoneScope scope;
+  Isolate* isolate = scope.main_isolate();
+  Zone* zone = scope.main_zone();
+  Factory* factory = isolate->factory();
+
+  ExpectedSnippet<0> snippets[] = {
+      {"return /abd/.exec('cccabbdd');", {factory->null_value()}},
+      {"return /ab+d/.exec('cccabbdd')[0];",
+       {factory->NewStringFromStaticChars("abbd")}},
+      {"var a = 3.1414;"
+       REPEAT_256(SPACE, "a = 3.1414;")
+       "return /ab+d/.exec('cccabbdd')[0];",
+       {factory->NewStringFromStaticChars("abbd")}},
+      {"return /ab+d/.exec('cccabbdd')[1];", {factory->undefined_value()}},
+      {"return /AbC/i.exec('ssaBC')[0];",
+       {factory->NewStringFromStaticChars("aBC")}},
+      {"return 'ssaBC'.match(/AbC/i)[0];",
+       {factory->NewStringFromStaticChars("aBC")}},
+      {"return 'ssaBCtAbC'.match(/(AbC)/gi)[1];",
+       {factory->NewStringFromStaticChars("AbC")}},
+  };
+
+  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
+  for (size_t i = 0; i < num_snippets; i++) {
+    ScopedVector<char> script(4096);
+    SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName,
+             snippets[i].code_snippet, kFunctionName);
+
+    BytecodeGraphTester tester(isolate, zone, script.start());
+    auto callable = tester.GetCallable<>();
+    Handle<Object> return_value = callable().ToHandleChecked();
+    CHECK(return_value->SameValue(*snippets[i].return_value()));
+  }
+}
+
+
+TEST(BytecodeGraphBuilderArrayLiterals) {
+  HandleAndZoneScope scope;
+  Isolate* isolate = scope.main_isolate();
+  Zone* zone = scope.main_zone();
+  Factory* factory = isolate->factory();
+
+  ExpectedSnippet<0> snippets[] = {
+      {"return [][0];", {factory->undefined_value()}},
+      {"return [1, 3, 2][1];", {factory->NewNumberFromInt(3)}},
+      {"var a;" REPEAT_256(SPACE, "a = 9.87;") "return [1, 3, 2][1];",
+       {factory->NewNumberFromInt(3)}},
+      {"return ['a', 'b', 'c'][2];", {factory->NewStringFromStaticChars("c")}},
+      {"var a = 100; return [a, a++, a + 2, a + 3][2];",
+       {factory->NewNumberFromInt(103)}},
+      {"var a = 100; return [a, ++a, a + 2, a + 3][1];",
+       {factory->NewNumberFromInt(101)}},
+      {"var a = 9.2;"
+       REPEAT_256(SPACE, "a = 9.34;")
+       "return [a, ++a, a + 2, a + 3][2];",
+       {factory->NewHeapNumber(12.34)}},
+      {"return [[1, 2, 3], ['a', 'b', 'c']][1][0];",
+       {factory->NewStringFromStaticChars("a")}},
+      {"var t = 't'; return [[t, t + 'est'], [1 + t]][0][1];",
+       {factory->NewStringFromStaticChars("test")}},
+      {"var t = 't'; return [[t, t + 'est'], [1 + t]][1][0];",
+       {factory->NewStringFromStaticChars("1t")}}};
+
+  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
+  for (size_t i = 0; i < num_snippets; i++) {
+    ScopedVector<char> script(4096);
+    SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName,
+             snippets[i].code_snippet, kFunctionName);
+
+    BytecodeGraphTester tester(isolate, zone, script.start());
+    auto callable = tester.GetCallable<>();
+    Handle<Object> return_value = callable().ToHandleChecked();
+    CHECK(return_value->SameValue(*snippets[i].return_value()));
+  }
+}
+
+
+TEST(BytecodeGraphBuilderObjectLiterals) {
+  HandleAndZoneScope scope;
+  Isolate* isolate = scope.main_isolate();
+  Zone* zone = scope.main_zone();
+  Factory* factory = isolate->factory();
+
+  ExpectedSnippet<0> snippets[] = {
+      {"return { }.name;", {factory->undefined_value()}},
+      {"return { name: 'string', val: 9.2 }.name;",
+       {factory->NewStringFromStaticChars("string")}},
+      {"var a;\n"
+       REPEAT_256(SPACE, "a = 1.23;\n")
+       "return { name: 'string', val: 9.2 }.name;",
+       {factory->NewStringFromStaticChars("string")}},
+      {"return { name: 'string', val: 9.2 }['name'];",
+       {factory->NewStringFromStaticChars("string")}},
+      {"var a = 15; return { name: 'string', val: a }.val;",
+       {factory->NewNumberFromInt(15)}},
+      {"var a;"
+       REPEAT_256(SPACE, "a = 1.23;")
+       "return { name: 'string', val: a }.val;",
+       {factory->NewHeapNumber(1.23)}},
+      {"var a = 15; var b = 'val'; return { name: 'string', val: a }[b];",
+       {factory->NewNumberFromInt(15)}},
+      {"var a = 5; return { val: a, val: a + 1 }.val;",
+       {factory->NewNumberFromInt(6)}},
+      {"return { func: function() { return 'test' } }.func();",
+       {factory->NewStringFromStaticChars("test")}},
+      {"return { func(a) { return a + 'st'; } }.func('te');",
+       {factory->NewStringFromStaticChars("test")}},
+      {"return { get a() { return 22; } }.a;", {factory->NewNumberFromInt(22)}},
+      {"var a = { get b() { return this.x + 't'; },\n"
+       "          set b(val) { this.x = val + 's' } };\n"
+       "a.b = 'te';\n"
+       "return a.b;",
+       {factory->NewStringFromStaticChars("test")}},
+      {"var a = 123; return { 1: a }[1];", {factory->NewNumberFromInt(123)}},
+      {"return Object.getPrototypeOf({ __proto__: null });",
+       {factory->null_value()}},
+      {"var a = 'test'; return { [a]: 1 }.test;",
+       {factory->NewNumberFromInt(1)}},
+      {"var a = 'test'; return { b: a, [a]: a + 'ing' }['test']",
+       {factory->NewStringFromStaticChars("testing")}},
+      {"var a = 'proto_str';\n"
+       "var b = { [a]: 1, __proto__: { var : a } };\n"
+       "return Object.getPrototypeOf(b).var",
+       {factory->NewStringFromStaticChars("proto_str")}},
+      {"var n = 'name';\n"
+       "return { [n]: 'val', get a() { return 987 } }['a'];",
+       {factory->NewNumberFromInt(987)}},
+  };
+
+  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
+  for (size_t i = 0; i < num_snippets; i++) {
+    ScopedVector<char> script(4096);
+    SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName,
+             snippets[i].code_snippet, kFunctionName);
+    BytecodeGraphTester tester(isolate, zone, script.start());
+    auto callable = tester.GetCallable<>();
+    Handle<Object> return_value = callable().ToHandleChecked();
+    CHECK(return_value->SameValue(*snippets[i].return_value()));
+  }
+}
+
+
+TEST(BytecodeGraphBuilderIf) {
+  HandleAndZoneScope scope;
+  Isolate* isolate = scope.main_isolate();
+  Zone* zone = scope.main_zone();
+  Factory* factory = isolate->factory();
+
+  ExpectedSnippet<1> snippets[] = {
+      {"if (p1 > 1) return 1;\n"
+       "return -1;",
+       {factory->NewNumberFromInt(1), factory->NewNumberFromInt(2)}},
+      {"if (p1 > 1) return 1;\n"
+       "return -1;",
+       {factory->NewNumberFromInt(-1), factory->NewNumberFromInt(1)}},
+      {"if (p1 > 1) { return 1; } else { return -1; }",
+       {factory->NewNumberFromInt(1), factory->NewNumberFromInt(2)}},
+      {"if (p1 > 1) { return 1; } else { return -1; }",
+       {factory->NewNumberFromInt(-1), factory->NewNumberFromInt(1)}},
+      {"if (p1 > 50) {\n"
+       "  return 1;\n"
+       "} else if (p1 < 10) {\n"
+       "   return 10;\n"
+       "} else {\n"
+       "   return -10;\n"
+       "}",
+       {factory->NewNumberFromInt(1), factory->NewNumberFromInt(51)}},
+      {"if (p1 > 50) {\n"
+       "  return 1;\n"
+       "} else if (p1 < 10) {\n"
+       "   return 10;\n"
+       "} else {\n"
+       "   return 100;\n"
+       "}",
+       {factory->NewNumberFromInt(10), factory->NewNumberFromInt(9)}},
+      {"if (p1 > 50) {\n"
+       "  return 1;\n"
+       "} else if (p1 < 10) {\n"
+       "   return 10;\n"
+       "} else {\n"
+       "   return 100;\n"
+       "}",
+       {factory->NewNumberFromInt(100), factory->NewNumberFromInt(10)}},
+      {"if (p1 >= 0) {\n"
+       "   if (p1 > 10) { return 2; } else { return 1; }\n"
+       "} else {\n"
+       "   if (p1 < -10) { return -2; } else { return -1; }\n"
+       "}",
+       {factory->NewNumberFromInt(2), factory->NewNumberFromInt(100)}},
+      {"if (p1 >= 0) {\n"
+       "   if (p1 > 10) { return 2; } else { return 1; }\n"
+       "} else {\n"
+       "   if (p1 < -10) { return -2; } else { return -1; }\n"
+       "}",
+       {factory->NewNumberFromInt(1), factory->NewNumberFromInt(10)}},
+      {"if (p1 >= 0) {\n"
+       "   if (p1 > 10) { return 2; } else { return 1; }\n"
+       "} else {\n"
+       "   if (p1 < -10) { return -2; } else { return -1; }\n"
+       "}",
+       {factory->NewNumberFromInt(-2), factory->NewNumberFromInt(-11)}},
+      {"if (p1 >= 0) {\n"
+       "   if (p1 > 10) { return 2; } else { return 1; }\n"
+       "} else {\n"
+       "   if (p1 < -10) { return -2; } else { return -1; }\n"
+       "}",
+       {factory->NewNumberFromInt(-1), factory->NewNumberFromInt(-10)}},
+  };
+
+  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
+  for (size_t i = 0; i < num_snippets; i++) {
+    ScopedVector<char> script(2048);
+    SNPrintF(script, "function %s(p1) { %s };\n%s(0);", kFunctionName,
+             snippets[i].code_snippet, kFunctionName);
+
+    BytecodeGraphTester tester(isolate, zone, script.start());
+    auto callable = tester.GetCallable<Handle<Object>>();
+    Handle<Object> return_value =
+        callable(snippets[i].parameter(0)).ToHandleChecked();
+    CHECK(return_value->SameValue(*snippets[i].return_value()));
+  }
+}
+
+
+TEST(BytecodeGraphBuilderConditionalOperator) {
+  HandleAndZoneScope scope;
+  Isolate* isolate = scope.main_isolate();
+  Zone* zone = scope.main_zone();
+  Factory* factory = isolate->factory();
+
+  ExpectedSnippet<1> snippets[] = {
+      {"return (p1 > 1) ? 1 : -1;",
+       {factory->NewNumberFromInt(1), factory->NewNumberFromInt(2)}},
+      {"return (p1 > 1) ? 1 : -1;",
+       {factory->NewNumberFromInt(-1), factory->NewNumberFromInt(0)}},
+      {"return (p1 > 50) ? 1 : ((p1 < 10) ? 10 : -10);",
+       {factory->NewNumberFromInt(10), factory->NewNumberFromInt(2)}},
+      {"return (p1 > 50) ? 1 : ((p1 < 10) ? 10 : -10);",
+       {factory->NewNumberFromInt(-10), factory->NewNumberFromInt(20)}},
+  };
+
+  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
+  for (size_t i = 0; i < num_snippets; i++) {
+    ScopedVector<char> script(2048);
+    SNPrintF(script, "function %s(p1) { %s };\n%s(0);", kFunctionName,
+             snippets[i].code_snippet, kFunctionName);
+
+    BytecodeGraphTester tester(isolate, zone, script.start());
+    auto callable = tester.GetCallable<Handle<Object>>();
+    Handle<Object> return_value =
+        callable(snippets[i].parameter(0)).ToHandleChecked();
+    CHECK(return_value->SameValue(*snippets[i].return_value()));
+  }
+}
+
+
+TEST(BytecodeGraphBuilderSwitch) {
+  HandleAndZoneScope scope;
+  Isolate* isolate = scope.main_isolate();
+  Zone* zone = scope.main_zone();
+  Factory* factory = isolate->factory();
+
+  const char* switch_code =
+      "switch (p1) {\n"
+      "  case 1: return 0;\n"
+      "  case 2: return 1;\n"
+      "  case 3:\n"
+      "  case 4: return 2;\n"
+      "  case 9: break;\n"
+      "  default: return 3;\n"
+      "}\n"
+      "return 9;";
+
+  ExpectedSnippet<1> snippets[] = {
+      {switch_code,
+       {factory->NewNumberFromInt(0), factory->NewNumberFromInt(1)}},
+      {switch_code,
+       {factory->NewNumberFromInt(1), factory->NewNumberFromInt(2)}},
+      {switch_code,
+       {factory->NewNumberFromInt(2), factory->NewNumberFromInt(3)}},
+      {switch_code,
+       {factory->NewNumberFromInt(2), factory->NewNumberFromInt(4)}},
+      {switch_code,
+       {factory->NewNumberFromInt(9), factory->NewNumberFromInt(9)}},
+      {switch_code,
+       {factory->NewNumberFromInt(3), factory->NewNumberFromInt(5)}},
+      {switch_code,
+       {factory->NewNumberFromInt(3), factory->NewNumberFromInt(6)}},
+  };
+
+  for (size_t i = 0; i < arraysize(snippets); i++) {
+    ScopedVector<char> script(2048);
+    SNPrintF(script, "function %s(p1) { %s };\n%s(0);", kFunctionName,
+             snippets[i].code_snippet, kFunctionName);
+
+    BytecodeGraphTester tester(isolate, zone, script.start());
+    auto callable = tester.GetCallable<Handle<Object>>();
+    Handle<Object> return_value =
+        callable(snippets[i].parameter(0)).ToHandleChecked();
+    CHECK(return_value->SameValue(*snippets[i].return_value()));
+  }
+}
+
+
+TEST(BytecodeGraphBuilderNestedSwitch) {
+  HandleAndZoneScope scope;
+  Isolate* isolate = scope.main_isolate();
+  Zone* zone = scope.main_zone();
+  Factory* factory = isolate->factory();
+
+  const char* switch_code =
+      "switch (p1) {\n"
+      "  case 0: {"
+      "    switch (p2) { case 0: return 0; case 1: return 1; case 2: break; }\n"
+      "    return -1;"
+      "  }\n"
+      "  case 1: {"
+      "    switch (p2) { case 0: return 2; case 1: return 3; }\n"
+      "  }\n"
+      "  case 2: break;"
+      "  }\n"
+      "return -2;";
+
+  ExpectedSnippet<2> snippets[] = {
+      {switch_code,
+       {factory->NewNumberFromInt(0), factory->NewNumberFromInt(0),
+        factory->NewNumberFromInt(0)}},
+      {switch_code,
+       {factory->NewNumberFromInt(1), factory->NewNumberFromInt(0),
+        factory->NewNumberFromInt(1)}},
+      {switch_code,
+       {factory->NewNumberFromInt(-1), factory->NewNumberFromInt(0),
+        factory->NewNumberFromInt(2)}},
+      {switch_code,
+       {factory->NewNumberFromInt(-1), factory->NewNumberFromInt(0),
+        factory->NewNumberFromInt(3)}},
+      {switch_code,
+       {factory->NewNumberFromInt(2), factory->NewNumberFromInt(1),
+        factory->NewNumberFromInt(0)}},
+      {switch_code,
+       {factory->NewNumberFromInt(3), factory->NewNumberFromInt(1),
+        factory->NewNumberFromInt(1)}},
+      {switch_code,
+       {factory->NewNumberFromInt(-2), factory->NewNumberFromInt(1),
+        factory->NewNumberFromInt(2)}},
+      {switch_code,
+       {factory->NewNumberFromInt(-2), factory->NewNumberFromInt(2),
+        factory->NewNumberFromInt(0)}},
+  };
+
+  for (size_t i = 0; i < arraysize(snippets); i++) {
+    ScopedVector<char> script(2048);
+    SNPrintF(script, "function %s(p1, p2) { %s };\n%s(0, 0);", kFunctionName,
+             snippets[i].code_snippet, kFunctionName);
+
+    BytecodeGraphTester tester(isolate, zone, script.start());
+    auto callable = tester.GetCallable<Handle<Object>, Handle<Object>>();
+    Handle<Object> return_value =
+        callable(snippets[i].parameter(0), snippets[i].parameter(1))
+            .ToHandleChecked();
+    CHECK(return_value->SameValue(*snippets[i].return_value()));
+  }
+}
+
+
+TEST(BytecodeGraphBuilderBreakableBlocks) {
+  HandleAndZoneScope scope;
+  Isolate* isolate = scope.main_isolate();
+  Zone* zone = scope.main_zone();
+  Factory* factory = isolate->factory();
+
+  ExpectedSnippet<0> snippets[] = {
+      {"var x = 0;\n"
+       "my_heart: {\n"
+       "  x = x + 1;\n"
+       "  break my_heart;\n"
+       "  x = x + 2;\n"
+       "}\n"
+       "return x;\n",
+       {factory->NewNumberFromInt(1)}},
+      {"var sum = 0;\n"
+       "outta_here: {\n"
+       "  for (var x = 0; x < 10; ++x) {\n"
+       "    for (var y = 0; y < 3; ++y) {\n"
+       "      ++sum;\n"
+       "      if (x + y == 12) { break outta_here; }\n"
+       "    }\n"
+       "  }\n"
+       "}\n"
+       "return sum;",
+       {factory->NewNumber(30)}},
+  };
+
+  for (size_t i = 0; i < arraysize(snippets); i++) {
+    ScopedVector<char> script(1024);
+    SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName,
+             snippets[i].code_snippet, kFunctionName);
+
+    BytecodeGraphTester tester(isolate, zone, script.start());
+    auto callable = tester.GetCallable<>();
+    Handle<Object> return_value = callable().ToHandleChecked();
+    CHECK(return_value->SameValue(*snippets[i].return_value()));
+  }
+}
+
+
+TEST(BytecodeGraphBuilderWhile) {
+  HandleAndZoneScope scope;
+  Isolate* isolate = scope.main_isolate();
+  Zone* zone = scope.main_zone();
+  Factory* factory = isolate->factory();
+
+  ExpectedSnippet<0> snippets[] = {
+      {"var x = 1; while (x < 1) { x *= 100; } return x;",
+       {factory->NewNumberFromInt(1)}},
+      {"var x = 1, y = 0; while (x < 7) { y += x * x; x += 1; } return y;",
+       {factory->NewNumberFromInt(91)}},
+      {"var x = 1; while (true) { x += 1; if (x == 10) break; } return x;",
+       {factory->NewNumberFromInt(10)}},
+      {"var x = 1; while (false) { x += 1; } return x;",
+       {factory->NewNumberFromInt(1)}},
+      {"var x = 0;\n"
+       "while (true) {\n"
+       "  while (x < 10) {\n"
+       "    x = x * x + 1;\n"
+       "  }"
+       "  x += 1;\n"
+       "  break;\n"
+       "}\n"
+       "return x;",
+       {factory->NewNumberFromInt(27)}},
+      {"var x = 1, y = 0;\n"
+       "while (x < 7) {\n"
+       "  x += 1;\n"
+       "  if (x == 2) continue;\n"
+       "  if (x == 3) continue;\n"
+       "  y += x * x;\n"
+       "  if (x == 4) break;\n"
+       "}\n"
+       "return y;",
+       {factory->NewNumberFromInt(16)}}};
+
+  for (size_t i = 0; i < arraysize(snippets); i++) {
+    ScopedVector<char> script(1024);
+    SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName,
+             snippets[i].code_snippet, kFunctionName);
+
+    BytecodeGraphTester tester(isolate, zone, script.start());
+    auto callable = tester.GetCallable<>();
+    Handle<Object> return_value = callable().ToHandleChecked();
+    CHECK(return_value->SameValue(*snippets[i].return_value()));
+  }
+}
+
+
+TEST(BytecodeGraphBuilderDo) {
+  HandleAndZoneScope scope;
+  Isolate* isolate = scope.main_isolate();
+  Zone* zone = scope.main_zone();
+  Factory* factory = isolate->factory();
+
+  ExpectedSnippet<0> snippets[] = {
+      {"var x = 1; do { x *= 100; } while (x < 100); return x;",
+       {factory->NewNumberFromInt(100)}},
+      {"var x = 1; do { x = x * x + 1; } while (x < 7) return x;",
+       {factory->NewNumberFromInt(26)}},
+      {"var x = 1; do { x += 1; } while (false); return x;",
+       {factory->NewNumberFromInt(2)}},
+      {"var x = 1, y = 0;\n"
+       "do {\n"
+       "  x += 1;\n"
+       "  if (x == 2) continue;\n"
+       "  if (x == 3) continue;\n"
+       "  y += x * x;\n"
+       "  if (x == 4) break;\n"
+       "} while (x < 7);\n"
+       "return y;",
+       {factory->NewNumberFromInt(16)}}};
+
+  for (size_t i = 0; i < arraysize(snippets); i++) {
+    ScopedVector<char> script(1024);
+    SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName,
+             snippets[i].code_snippet, kFunctionName);
+
+    BytecodeGraphTester tester(isolate, zone, script.start());
+    auto callable = tester.GetCallable<>();
+    Handle<Object> return_value = callable().ToHandleChecked();
+    CHECK(return_value->SameValue(*snippets[i].return_value()));
+  }
+}
+
+
+TEST(BytecodeGraphBuilderFor) {
+  HandleAndZoneScope scope;
+  Isolate* isolate = scope.main_isolate();
+  Zone* zone = scope.main_zone();
+  Factory* factory = isolate->factory();
+
+  ExpectedSnippet<0> snippets[] = {
+      {"for (var x = 0;; x = 2 * x + 1) { if (x > 10) return x; }",
+       {factory->NewNumberFromInt(15)}},
+      {"for (var x = 0; true; x = 2 * x + 1) { if (x > 100) return x; }",
+       {factory->NewNumberFromInt(127)}},
+      {"for (var x = 0; false; x = 2 * x + 1) { if (x > 100) return x; } "
+       "return 0;",
+       {factory->NewNumberFromInt(0)}},
+      {"for (var x = 0; x < 200; x = 2 * x + 1) { x = x; } return x;",
+       {factory->NewNumberFromInt(255)}},
+      {"for (var x = 0; x < 200; x = 2 * x + 1) {} return x;",
+       {factory->NewNumberFromInt(255)}},
+      {"var sum = 0;\n"
+       "for (var x = 0; x < 200; x += 1) {\n"
+       "  if (x % 2) continue;\n"
+       "  if (sum > 10) break;\n"
+       "  sum += x;\n"
+       "}\n"
+       "return sum;",
+       {factory->NewNumberFromInt(12)}},
+      {"var sum = 0;\n"
+       "for (var w = 0; w < 2; w++) {\n"
+       "  for (var x = 0; x < 200; x += 1) {\n"
+       "    if (x % 2) continue;\n"
+       "    if (x > 4) break;\n"
+       "    sum += x + w;\n"
+       "  }\n"
+       "}\n"
+       "return sum;",
+       {factory->NewNumberFromInt(15)}},
+      {"var sum = 0;\n"
+       "for (var w = 0; w < 2; w++) {\n"
+       "  if (w == 1) break;\n"
+       "  for (var x = 0; x < 200; x += 1) {\n"
+       "    if (x % 2) continue;\n"
+       "    if (x > 4) break;\n"
+       "    sum += x + w;\n"
+       "  }\n"
+       "}\n"
+       "return sum;",
+       {factory->NewNumberFromInt(6)}},
+      {"var sum = 0;\n"
+       "for (var w = 0; w < 3; w++) {\n"
+       "  if (w == 1) continue;\n"
+       "  for (var x = 0; x < 200; x += 1) {\n"
+       "    if (x % 2) continue;\n"
+       "    if (x > 4) break;\n"
+       "    sum += x + w;\n"
+       "  }\n"
+       "}\n"
+       "return sum;",
+       {factory->NewNumberFromInt(18)}},
+      {"var sum = 0;\n"
+       "for (var x = 1; x < 10; x += 2) {\n"
+       "  for (var y = x; y < x + 2; y++) {\n"
+       "    sum += y * y;\n"
+       "  }\n"
+       "}\n"
+       "return sum;",
+       {factory->NewNumberFromInt(385)}},
+  };
+
+  for (size_t i = 0; i < arraysize(snippets); i++) {
+    ScopedVector<char> script(1024);
+    SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName,
+             snippets[i].code_snippet, kFunctionName);
+
+    BytecodeGraphTester tester(isolate, zone, script.start());
+    auto callable = tester.GetCallable<>();
+    Handle<Object> return_value = callable().ToHandleChecked();
+    CHECK(return_value->SameValue(*snippets[i].return_value()));
+  }
+}
+
+
+TEST(BytecodeGraphBuilderForIn) {
+  HandleAndZoneScope scope;
+  Isolate* isolate = scope.main_isolate();
+  Zone* zone = scope.main_zone();
+  Factory* factory = isolate->factory();
+  ExpectedSnippet<0> snippets[] = {
+      {"var sum = 0;\n"
+       "var empty = null;\n"
+       "for (var x in empty) { sum++; }\n"
+       "return sum;",
+       {factory->NewNumberFromInt(0)}},
+      {"var sum = 100;\n"
+       "var empty = 1;\n"
+       "for (var x in empty) { sum++; }\n"
+       "return sum;",
+       {factory->NewNumberFromInt(100)}},
+      {"for (var x in [ 10, 20, 30 ]) {}\n"
+       "return 2;",
+       {factory->NewNumberFromInt(2)}},
+      {"var last = 0;\n"
+       "for (var x in [ 10, 20, 30 ]) {\n"
+       "  last = x;\n"
+       "}\n"
+       "return +last;",
+       {factory->NewNumberFromInt(2)}},
+      {"var first = -1;\n"
+       "for (var x in [ 10, 20, 30 ]) {\n"
+       "  first = +x;\n"
+       "  if (first > 0) break;\n"
+       "}\n"
+       "return first;",
+       {factory->NewNumberFromInt(1)}},
+      {"var first = -1;\n"
+       "for (var x in [ 10, 20, 30 ]) {\n"
+       "  if (first >= 0) continue;\n"
+       "  first = x;\n"
+       "}\n"
+       "return +first;",
+       {factory->NewNumberFromInt(0)}},
+      {"var sum = 0;\n"
+       "for (var x in [ 10, 20, 30 ]) {\n"
+       "  for (var y in [ 11, 22, 33, 44, 55, 66, 77 ]) {\n"
+       "    sum += 1;\n"
+       "  }\n"
+       "}\n"
+       "return sum;",
+       {factory->NewNumberFromInt(21)}},
+      {"var sum = 0;\n"
+       "for (var x in [ 10, 20, 30 ]) {\n"
+       "  for (var y in [ 11, 22, 33, 44, 55, 66, 77 ]) {\n"
+       "    if (sum == 7) break;\n"
+       "    if (sum == 6) continue;\n"
+       "    sum += 1;\n"
+       "  }\n"
+       "}\n"
+       "return sum;",
+       {factory->NewNumberFromInt(6)}},
+  };
+
+  for (size_t i = 0; i < arraysize(snippets); i++) {
+    ScopedVector<char> script(1024);
+    SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName,
+             snippets[i].code_snippet, kFunctionName);
+
+    BytecodeGraphTester tester(isolate, zone, script.start());
+    auto callable = tester.GetCallable<>();
+    Handle<Object> return_value = callable().ToHandleChecked();
+    CHECK(return_value->SameValue(*snippets[i].return_value()));
+  }
+}
+
+
+TEST(JumpWithConstantsAndWideConstants) {
+  HandleAndZoneScope scope;
+  auto isolate = scope.main_isolate();
+  const int kStep = 19;
+  int start = 7;
+  for (int constants = start; constants < 256 + 3 * kStep; constants += kStep) {
+    std::stringstream filler_os;
+    // Generate a string that consumes constant pool entries and
+    // spread out branch distances in script below.
+    for (int i = 0; i < constants; i++) {
+      filler_os << "var x_ = 'x_" << i << "';\n";
+    }
+    std::string filler(filler_os.str());
+
+    std::stringstream script_os;
+    script_os << "function " << kFunctionName << "(a) {\n";
+    script_os << "  " << filler;
+    script_os << "  for (var i = a; i < 2; i++) {\n";
+    script_os << "  " << filler;
+    script_os << "    if (i == 0) { " << filler << "i = 10; continue; }\n";
+    script_os << "    else if (i == a) { " << filler << "i = 12; break; }\n";
+    script_os << "    else { " << filler << " }\n";
+    script_os << "  }\n";
+    script_os << "  return i;\n";
+    script_os << "}\n";
+    script_os << kFunctionName << "(0);\n";
+    std::string script(script_os.str());
+    auto factory = isolate->factory();
+    auto zone = scope.main_zone();
+    for (int a = 0; a < 3; a++) {
+      BytecodeGraphTester tester(isolate, zone, script.c_str());
+      auto callable = tester.GetCallable<Handle<Object>>();
+      Handle<Object> return_val =
+          callable(factory->NewNumberFromInt(a)).ToHandleChecked();
+      static const int results[] = {11, 12, 2};
+      CHECK_EQ(Handle<Smi>::cast(return_val)->value(), results[a]);
+    }
+  }
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/test/cctest/compiler/test-run-deopt.cc b/test/cctest/compiler/test-run-deopt.cc
index 14c024c..8b4c9dc 100644
--- a/test/cctest/compiler/test-run-deopt.cc
+++ b/test/cctest/compiler/test-run-deopt.cc
@@ -2,18 +2,15 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "src/v8.h"
-
+#include "src/frames-inl.h"
 #include "test/cctest/cctest.h"
 #include "test/cctest/compiler/function-tester.h"
 
-using namespace v8;
-using namespace v8::internal;
-using namespace v8::internal::compiler;
+namespace v8 {
+namespace internal {
+namespace compiler {
 
-#if V8_TURBOFAN_TARGET
-
-static void IsOptimized(const FunctionCallbackInfo<v8::Value>& args) {
+static void IsOptimized(const v8::FunctionCallbackInfo<v8::Value>& args) {
   JavaScriptFrameIterator it(CcTest::i_isolate());
   JavaScriptFrame* frame = it.frame();
   return args.GetReturnValue().Set(frame->is_optimized());
@@ -21,56 +18,104 @@
 
 
 static void InstallIsOptimizedHelper(v8::Isolate* isolate) {
-  Local<v8::Context> context = isolate->GetCurrentContext();
-  Local<v8::FunctionTemplate> t = FunctionTemplate::New(isolate, IsOptimized);
-  context->Global()->Set(v8_str("IsOptimized"), t->GetFunction());
+  v8::Local<v8::Context> context = isolate->GetCurrentContext();
+  v8::Local<v8::FunctionTemplate> t =
+      v8::FunctionTemplate::New(isolate, IsOptimized);
+  CHECK(context->Global()
+            ->Set(context, v8_str("IsOptimized"),
+                  t->GetFunction(context).ToLocalChecked())
+            .FromJust());
 }
 
 
-TEST(TurboSimpleDeopt) {
+TEST(DeoptSimple) {
   FLAG_allow_natives_syntax = true;
-  FLAG_turbo_deoptimization = true;
 
   FunctionTester T(
       "(function f(a) {"
-      "var b = 1;"
-      "if (!IsOptimized()) return 0;"
-      "%DeoptimizeFunction(f);"
-      "if (IsOptimized()) return 0;"
-      "return a + b; })");
+      "  var b = 1;"
+      "  if (!IsOptimized()) return 0;"
+      "  %DeoptimizeFunction(f);"
+      "  if (IsOptimized()) return 0;"
+      "  return a + b;"
+      "})");
 
   InstallIsOptimizedHelper(CcTest::isolate());
   T.CheckCall(T.Val(2), T.Val(1));
 }
 
 
-TEST(TurboSimpleDeoptInExpr) {
+TEST(DeoptSimpleInExpr) {
   FLAG_allow_natives_syntax = true;
-  FLAG_turbo_deoptimization = true;
 
   FunctionTester T(
       "(function f(a) {"
-      "var b = 1;"
-      "var c = 2;"
-      "if (!IsOptimized()) return 0;"
-      "var d = b + (%DeoptimizeFunction(f), c);"
-      "if (IsOptimized()) return 0;"
-      "return d + a; })");
+      "  var b = 1;"
+      "  var c = 2;"
+      "  if (!IsOptimized()) return 0;"
+      "  var d = b + (%DeoptimizeFunction(f), c);"
+      "  if (IsOptimized()) return 0;"
+      "  return d + a;"
+      "})");
 
   InstallIsOptimizedHelper(CcTest::isolate());
   T.CheckCall(T.Val(6), T.Val(3));
 }
 
-#endif
 
-TEST(TurboTrivialDeopt) {
+TEST(DeoptExceptionHandlerCatch) {
   FLAG_allow_natives_syntax = true;
-  FLAG_turbo_deoptimization = true;
+
+  FunctionTester T(
+      "(function f() {"
+      "  var is_opt = IsOptimized;"
+      "  try {"
+      "    DeoptAndThrow(f);"
+      "  } catch (e) {"
+      "    return is_opt();"
+      "  }"
+      "})");
+
+  CompileRun("function DeoptAndThrow(f) { %DeoptimizeFunction(f); throw 0; }");
+  InstallIsOptimizedHelper(CcTest::isolate());
+  T.CheckCall(T.false_value());
+}
+
+
+TEST(DeoptExceptionHandlerFinally) {
+  FLAG_allow_natives_syntax = true;
+  FLAG_turbo_try_finally = true;
+
+  FunctionTester T(
+      "(function f() {"
+      "  var is_opt = IsOptimized;"
+      "  try {"
+      "    DeoptAndThrow(f);"
+      "  } finally {"
+      "    return is_opt();"
+      "  }"
+      "})");
+
+  CompileRun("function DeoptAndThrow(f) { %DeoptimizeFunction(f); throw 0; }");
+  InstallIsOptimizedHelper(CcTest::isolate());
+#if 0  // TODO(4195,mstarzinger): Reproduces on MIPS64, re-enable once fixed.
+  T.CheckCall(T.false_value());
+#endif
+}
+
+
+TEST(DeoptTrivial) {
+  FLAG_allow_natives_syntax = true;
 
   FunctionTester T(
       "(function foo() {"
-      "%DeoptimizeFunction(foo);"
-      "return 1; })");
+      "  %DeoptimizeFunction(foo);"
+      "  return 1;"
+      "})");
 
   T.CheckCall(T.Val(1));
 }
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/test/cctest/compiler/test-run-inlining.cc b/test/cctest/compiler/test-run-inlining.cc
index 19b96ba..f332d74 100644
--- a/test/cctest/compiler/test-run-inlining.cc
+++ b/test/cctest/compiler/test-run-inlining.cc
@@ -2,49 +2,64 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "src/v8.h"
-
+#include "src/frames-inl.h"
 #include "test/cctest/compiler/function-tester.h"
 
-#if V8_TURBOFAN_TARGET
+namespace v8 {
+namespace internal {
+namespace compiler {
 
-using namespace v8::internal;
-using namespace v8::internal::compiler;
+namespace {
 
-// Helper to determine inline count via JavaScriptFrame::GetInlineCount.
+// Helper to determine inline count via JavaScriptFrame::GetFunctions.
 // Note that a count of 1 indicates that no inlining has occured.
-static void AssertInlineCount(const v8::FunctionCallbackInfo<v8::Value>& args) {
+void AssertInlineCount(const v8::FunctionCallbackInfo<v8::Value>& args) {
   StackTraceFrameIterator it(CcTest::i_isolate());
   int frames_seen = 0;
   JavaScriptFrame* topmost = it.frame();
   while (!it.done()) {
     JavaScriptFrame* frame = it.frame();
+    List<JSFunction*> functions(2);
+    frame->GetFunctions(&functions);
     PrintF("%d %s, inline count: %d\n", frames_seen,
            frame->function()->shared()->DebugName()->ToCString().get(),
-           frame->GetInlineCount());
+           functions.length());
     frames_seen++;
     it.Advance();
   }
-  CHECK_EQ(args[0]->ToInt32(args.GetIsolate())->Value(),
-           topmost->GetInlineCount());
+  List<JSFunction*> functions(2);
+  topmost->GetFunctions(&functions);
+  CHECK_EQ(args[0]
+               ->ToInt32(args.GetIsolate()->GetCurrentContext())
+               .ToLocalChecked()
+               ->Value(),
+           functions.length());
 }
 
 
-static void InstallAssertInlineCountHelper(v8::Isolate* isolate) {
+void InstallAssertInlineCountHelper(v8::Isolate* isolate) {
   v8::Local<v8::Context> context = isolate->GetCurrentContext();
   v8::Local<v8::FunctionTemplate> t =
       v8::FunctionTemplate::New(isolate, AssertInlineCount);
-  context->Global()->Set(v8_str("AssertInlineCount"), t->GetFunction());
+  CHECK(context->Global()
+            ->Set(context, v8_str("AssertInlineCount"),
+                  t->GetFunction(context).ToLocalChecked())
+            .FromJust());
 }
 
 
-static uint32_t kInlineFlags = CompilationInfo::kInliningEnabled |
-                               CompilationInfo::kContextSpecializing |
-                               CompilationInfo::kTypingEnabled;
+const uint32_t kRestrictedInliningFlags =
+    CompilationInfo::kFunctionContextSpecializing |
+    CompilationInfo::kTypingEnabled;
+
+const uint32_t kInlineFlags = CompilationInfo::kInliningEnabled |
+                              CompilationInfo::kFunctionContextSpecializing |
+                              CompilationInfo::kTypingEnabled;
+
+}  // namespace
 
 
 TEST(SimpleInlining) {
-  FLAG_turbo_deoptimization = true;
   FunctionTester T(
       "(function(){"
       "  function foo(s) { AssertInlineCount(2); return s; };"
@@ -59,7 +74,6 @@
 
 
 TEST(SimpleInliningDeopt) {
-  FLAG_turbo_deoptimization = true;
   FunctionTester T(
       "(function(){"
       "  function foo(s) { %DeoptimizeFunction(bar); return s; };"
@@ -73,8 +87,21 @@
 }
 
 
+TEST(SimpleInliningDeoptSelf) {
+  FunctionTester T(
+      "(function(){"
+      "  function foo(s) { %_DeoptimizeNow(); return s; };"
+      "  function bar(s, t) { return foo(s); };"
+      "  return bar;"
+      "})();",
+      kInlineFlags);
+
+  InstallAssertInlineCountHelper(CcTest::isolate());
+  T.CheckCall(T.Val(1), T.Val(1), T.Val(2));
+}
+
+
 TEST(SimpleInliningContext) {
-  FLAG_turbo_deoptimization = true;
   FunctionTester T(
       "(function () {"
       "  function foo(s) { AssertInlineCount(2); var x = 12; return s + x; };"
@@ -89,7 +116,6 @@
 
 
 TEST(SimpleInliningContextDeopt) {
-  FLAG_turbo_deoptimization = true;
   FunctionTester T(
       "(function () {"
       "  function foo(s) {"
@@ -107,7 +133,6 @@
 
 
 TEST(CaptureContext) {
-  FLAG_turbo_deoptimization = true;
   FunctionTester T(
       "var f = (function () {"
       "  var x = 42;"
@@ -125,7 +150,6 @@
 // TODO(sigurds) For now we do not inline any native functions. If we do at
 // some point, change this test.
 TEST(DontInlineEval) {
-  FLAG_turbo_deoptimization = true;
   FunctionTester T(
       "var x = 42;"
       "(function () {"
@@ -140,12 +164,12 @@
 
 
 TEST(InlineOmitArguments) {
-  FLAG_turbo_deoptimization = true;
   FunctionTester T(
       "(function () {"
       "  var x = 42;"
       "  function bar(s, t, u, v) { AssertInlineCount(2); return x + s; };"
-      "  return (function (s,t) { return bar(s); });"
+      "  function foo(s, t) { return bar(s); };"
+      "  return foo;"
       "})();",
       kInlineFlags);
 
@@ -154,8 +178,23 @@
 }
 
 
+TEST(InlineOmitArgumentsObject) {
+  FunctionTester T(
+      "(function () {"
+      "  function bar(s, t, u, v) { AssertInlineCount(2); return arguments; };"
+      "  function foo(s, t) { var args = bar(s);"
+      "                       return args.length == 1 &&"
+      "                              args[0] == 11; };"
+      "  return foo;"
+      "})();",
+      kInlineFlags);
+
+  InstallAssertInlineCountHelper(CcTest::isolate());
+  T.CheckCall(T.true_value(), T.Val(11), T.undefined());
+}
+
+
 TEST(InlineOmitArgumentsDeopt) {
-  FLAG_turbo_deoptimization = true;
   FunctionTester T(
       "(function () {"
       "  function foo(s,t,u,v) { AssertInlineCount(2);"
@@ -173,12 +212,11 @@
 
 
 TEST(InlineSurplusArguments) {
-  FLAG_turbo_deoptimization = true;
   FunctionTester T(
       "(function () {"
       "  var x = 42;"
       "  function foo(s) { AssertInlineCount(2); return x + s; };"
-      "  function bar(s,t) { return foo(s,t,13); };"
+      "  function bar(s, t) { return foo(s, t, 13); };"
       "  return bar;"
       "})();",
       kInlineFlags);
@@ -188,8 +226,25 @@
 }
 
 
+TEST(InlineSurplusArgumentsObject) {
+  FunctionTester T(
+      "(function () {"
+      "  function foo(s) { AssertInlineCount(2); return arguments; };"
+      "  function bar(s, t) { var args = foo(s, t, 13);"
+      "                       return args.length == 3 &&"
+      "                              args[0] == 11 &&"
+      "                              args[1] == 12 &&"
+      "                              args[2] == 13; };"
+      "  return bar;"
+      "})();",
+      kInlineFlags);
+
+  InstallAssertInlineCountHelper(CcTest::isolate());
+  T.CheckCall(T.true_value(), T.Val(11), T.Val(12));
+}
+
+
 TEST(InlineSurplusArgumentsDeopt) {
-  FLAG_turbo_deoptimization = true;
   FunctionTester T(
       "(function () {"
       "  function foo(s) { AssertInlineCount(2); %DeoptimizeFunction(bar);"
@@ -209,7 +264,6 @@
 
 
 TEST(InlineTwice) {
-  FLAG_turbo_deoptimization = true;
   FunctionTester T(
       "(function () {"
       "  var x = 42;"
@@ -224,7 +278,6 @@
 
 
 TEST(InlineTwiceDependent) {
-  FLAG_turbo_deoptimization = true;
   FunctionTester T(
       "(function () {"
       "  var x = 42;"
@@ -240,7 +293,6 @@
 
 
 TEST(InlineTwiceDependentDiamond) {
-  FLAG_turbo_deoptimization = true;
   FunctionTester T(
       "(function () {"
       "  var x = 41;"
@@ -257,7 +309,6 @@
 
 
 TEST(InlineTwiceDependentDiamondDifferent) {
-  FLAG_turbo_deoptimization = true;
   FunctionTester T(
       "(function () {"
       "  var x = 41;"
@@ -274,7 +325,6 @@
 
 
 TEST(InlineLoopGuardedEmpty) {
-  FLAG_turbo_deoptimization = true;
   FunctionTester T(
       "(function () {"
       "  function foo(s) { AssertInlineCount(2); if (s) while (s); return s; };"
@@ -289,7 +339,6 @@
 
 
 TEST(InlineLoopGuardedOnce) {
-  FLAG_turbo_deoptimization = true;
   FunctionTester T(
       "(function () {"
       "  function foo(s,t) { AssertInlineCount(2); if (t > 0) while (s > 0) {"
@@ -305,7 +354,6 @@
 
 
 TEST(InlineLoopGuardedTwice) {
-  FLAG_turbo_deoptimization = true;
   FunctionTester T(
       "(function () {"
       "  function foo(s,t) { AssertInlineCount(2); if (t > 0) while (s > 0) {"
@@ -320,8 +368,51 @@
 }
 
 
+TEST(InlineLoopUnguardedEmpty) {
+  FunctionTester T(
+      "(function () {"
+      "  function foo(s) { AssertInlineCount(2); while (s); return s; };"
+      "  function bar(s, t) { return foo(s); };"
+      "  return bar;"
+      "})();",
+      kInlineFlags);
+
+  InstallAssertInlineCountHelper(CcTest::isolate());
+  T.CheckCall(T.Val(0.0), T.Val(0.0), T.Val(4));
+}
+
+
+TEST(InlineLoopUnguardedOnce) {
+  FunctionTester T(
+      "(function () {"
+      "  function foo(s) { AssertInlineCount(2); while (s) {"
+      "                    s = s - 1; }; return s; };"
+      "  function bar(s, t) { return foo(s); };"
+      "  return bar;"
+      "})();",
+      kInlineFlags);
+
+  InstallAssertInlineCountHelper(CcTest::isolate());
+  T.CheckCall(T.Val(0.0), T.Val(0.0), T.Val(4));
+}
+
+
+TEST(InlineLoopUnguardedTwice) {
+  FunctionTester T(
+      "(function () {"
+      "  function foo(s) { AssertInlineCount(2); while (s > 0) {"
+      "                    s = s - 1; }; return s; };"
+      "  function bar(s,t) { return foo(foo(s,t),t); };"
+      "  return bar;"
+      "})();",
+      kInlineFlags);
+
+  InstallAssertInlineCountHelper(CcTest::isolate());
+  T.CheckCall(T.Val(0.0), T.Val(0.0), T.Val(4));
+}
+
+
 TEST(InlineStrictIntoNonStrict) {
-  FLAG_turbo_deoptimization = true;
   FunctionTester T(
       "(function () {"
       "  var x = Object.create({}, { y: { value:42, writable:false } });"
@@ -338,7 +429,6 @@
 
 
 TEST(InlineNonStrictIntoStrict) {
-  FLAG_turbo_deoptimization = true;
   FunctionTester T(
       "(function () {"
       "  var x = Object.create({}, { y: { value:42, writable:false } });"
@@ -354,7 +444,6 @@
 
 
 TEST(InlineIntrinsicIsSmi) {
-  FLAG_turbo_deoptimization = true;
   FunctionTester T(
       "(function () {"
       "  var x = 42;"
@@ -368,23 +457,7 @@
 }
 
 
-TEST(InlineIntrinsicIsNonNegativeSmi) {
-  FLAG_turbo_deoptimization = true;
-  FunctionTester T(
-      "(function () {"
-      "  var x = 42;"
-      "  function bar(s,t) { return %_IsNonNegativeSmi(x); };"
-      "  return bar;"
-      "})();",
-      kInlineFlags);
-
-  InstallAssertInlineCountHelper(CcTest::isolate());
-  T.CheckCall(T.true_value(), T.Val(12), T.Val(4));
-}
-
-
 TEST(InlineIntrinsicIsArray) {
-  FLAG_turbo_deoptimization = true;
   FunctionTester T(
       "(function () {"
       "  var x = [1,2,3];"
@@ -419,7 +492,6 @@
 
 
 TEST(InlineWithArguments) {
-  FLAG_turbo_deoptimization = true;
   FunctionTester T(
       "(function () {"
       "  function foo(s,t,u) { AssertInlineCount(2);"
@@ -437,4 +509,99 @@
   T.CheckCall(T.true_value(), T.Val(12), T.Val(14));
 }
 
-#endif  // V8_TURBOFAN_TARGET
+
+TEST(InlineBuiltin) {
+  FunctionTester T(
+      "(function () {"
+      "  function foo(s,t,u) { AssertInlineCount(2); return true; }"
+      "  function bar() { return foo(); };"
+      "  %SetForceInlineFlag(foo);"
+      "  return bar;"
+      "})();",
+      kRestrictedInliningFlags);
+
+  InstallAssertInlineCountHelper(CcTest::isolate());
+  T.CheckCall(T.true_value());
+}
+
+
+TEST(InlineNestedBuiltin) {
+  FunctionTester T(
+      "(function () {"
+      "  function foo(s,t,u) { AssertInlineCount(3); return true; }"
+      "  function baz(s,t,u) { return foo(s,t,u); }"
+      "  function bar() { return baz(); };"
+      "  %SetForceInlineFlag(foo);"
+      "  %SetForceInlineFlag(baz);"
+      "  return bar;"
+      "})();",
+      kRestrictedInliningFlags);
+
+  InstallAssertInlineCountHelper(CcTest::isolate());
+  T.CheckCall(T.true_value());
+}
+
+
+TEST(StrongModeArity) {
+  FLAG_strong_mode = true;
+  FunctionTester T(
+      "(function () {"
+      "  function foo(x, y) { 'use strong'; return x; }"
+      "  function bar(x, y) { return foo(x); }"
+      "  return bar;"
+      "})();",
+      kInlineFlags);
+  T.CheckThrows(T.undefined(), T.undefined());
+}
+
+
+TEST(StrongModeArityOuter) {
+  FLAG_strong_mode = true;
+  FunctionTester T(
+      "(function () {"
+      "  'use strong';"
+      "  function foo(x, y) { return x; }"
+      "  function bar(x, y) { return foo(x); }"
+      "  return bar;"
+      "})();",
+      kInlineFlags);
+  T.CheckThrows(T.undefined(), T.undefined());
+}
+
+
+TEST(InlineSelfRecursive) {
+  FunctionTester T(
+      "(function () {"
+      "  function foo(x) { "
+      "    AssertInlineCount(1);"
+      "    if (x == 1) return foo(12);"
+      "    return x;"
+      "  }"
+      "  return foo;"
+      "})();",
+      kInlineFlags);
+
+  InstallAssertInlineCountHelper(CcTest::isolate());
+  T.CheckCall(T.Val(12), T.Val(1));
+}
+
+
+TEST(InlineMutuallyRecursive) {
+  FunctionTester T(
+      "(function () {"
+      "  function bar(x) { AssertInlineCount(2); return foo(x); }"
+      "  function foo(x) { "
+      "    if (x == 1) return bar(42);"
+      "    return x;"
+      "  }"
+      "  return foo;"
+      "})();",
+      kInlineFlags);
+
+  InstallAssertInlineCountHelper(CcTest::isolate());
+  T.CheckCall(T.Val(42), T.Val(1));
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/test/cctest/compiler/test-run-intrinsics.cc b/test/cctest/compiler/test-run-intrinsics.cc
index 76cbb8f..b201711 100644
--- a/test/cctest/compiler/test-run-intrinsics.cc
+++ b/test/cctest/compiler/test-run-intrinsics.cc
@@ -2,123 +2,25 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "src/v8.h"
-
 #include "test/cctest/compiler/function-tester.h"
 
-using namespace v8::internal;
-using namespace v8::internal::compiler;
+namespace v8 {
+namespace internal {
+namespace compiler {
+
 uint32_t flags = CompilationInfo::kInliningEnabled;
 
-TEST(IsSmi) {
-  FLAG_turbo_inlining_intrinsics = true;
-  FLAG_turbo_deoptimization = true;
-  FunctionTester T("(function(a) { return %_IsSmi(a); })", flags);
 
-  T.CheckTrue(T.Val(1));
-  T.CheckFalse(T.Val(1.1));
-  T.CheckFalse(T.Val(-0.0));
-  T.CheckTrue(T.Val(-2));
-  T.CheckFalse(T.Val(-2.3));
-  T.CheckFalse(T.undefined());
-}
+TEST(Call) {
+  FunctionTester T("(function(a,b) { return %_Call(b, a, 1, 2, 3); })", flags);
+  CompileRun("function f(a,b,c) { return a + b + c + this.d; }");
 
-
-TEST(IsNonNegativeSmi) {
-  FLAG_turbo_inlining_intrinsics = true;
-  FLAG_turbo_deoptimization = true;
-  FunctionTester T("(function(a) { return %_IsNonNegativeSmi(a); })", flags);
-
-  T.CheckTrue(T.Val(1));
-  T.CheckFalse(T.Val(1.1));
-  T.CheckFalse(T.Val(-0.0));
-  T.CheckFalse(T.Val(-2));
-  T.CheckFalse(T.Val(-2.3));
-  T.CheckFalse(T.undefined());
-}
-
-
-TEST(IsMinusZero) {
-  FLAG_turbo_inlining_intrinsics = true;
-  FLAG_turbo_deoptimization = true;
-  FunctionTester T("(function(a) { return %_IsMinusZero(a); })", flags);
-
-  T.CheckFalse(T.Val(1));
-  T.CheckFalse(T.Val(1.1));
-  T.CheckTrue(T.Val(-0.0));
-  T.CheckFalse(T.Val(-2));
-  T.CheckFalse(T.Val(-2.3));
-  T.CheckFalse(T.undefined());
-}
-
-
-TEST(IsArray) {
-  FLAG_turbo_inlining_intrinsics = true;
-  FLAG_turbo_deoptimization = true;
-  FunctionTester T("(function(a) { return %_IsArray(a); })", flags);
-
-  T.CheckFalse(T.NewObject("(function() {})"));
-  T.CheckTrue(T.NewObject("([1])"));
-  T.CheckFalse(T.NewObject("({})"));
-  T.CheckFalse(T.NewObject("(/x/)"));
-  T.CheckFalse(T.undefined());
-  T.CheckFalse(T.null());
-  T.CheckFalse(T.Val("x"));
-  T.CheckFalse(T.Val(1));
-}
-
-
-TEST(IsObject) {
-  FLAG_turbo_inlining_intrinsics = true;
-  FLAG_turbo_deoptimization = true;
-  FunctionTester T("(function(a) { return %_IsObject(a); })", flags);
-
-  T.CheckFalse(T.NewObject("(function() {})"));
-  T.CheckTrue(T.NewObject("([1])"));
-  T.CheckTrue(T.NewObject("({})"));
-  T.CheckTrue(T.NewObject("(/x/)"));
-  T.CheckFalse(T.undefined());
-  T.CheckTrue(T.null());
-  T.CheckFalse(T.Val("x"));
-  T.CheckFalse(T.Val(1));
-}
-
-
-TEST(IsFunction) {
-  FLAG_turbo_inlining_intrinsics = true;
-  FLAG_turbo_deoptimization = true;
-  FunctionTester T("(function(a) { return %_IsFunction(a); })", flags);
-
-  T.CheckTrue(T.NewObject("(function() {})"));
-  T.CheckFalse(T.NewObject("([1])"));
-  T.CheckFalse(T.NewObject("({})"));
-  T.CheckFalse(T.NewObject("(/x/)"));
-  T.CheckFalse(T.undefined());
-  T.CheckFalse(T.null());
-  T.CheckFalse(T.Val("x"));
-  T.CheckFalse(T.Val(1));
-}
-
-
-TEST(IsRegExp) {
-  FLAG_turbo_inlining_intrinsics = true;
-  FLAG_turbo_deoptimization = true;
-  FunctionTester T("(function(a) { return %_IsRegExp(a); })", flags);
-
-  T.CheckFalse(T.NewObject("(function() {})"));
-  T.CheckFalse(T.NewObject("([1])"));
-  T.CheckFalse(T.NewObject("({})"));
-  T.CheckTrue(T.NewObject("(/x/)"));
-  T.CheckFalse(T.undefined());
-  T.CheckFalse(T.null());
-  T.CheckFalse(T.Val("x"));
-  T.CheckFalse(T.Val(1));
+  T.CheckCall(T.Val(129), T.NewObject("({d:123})"), T.NewObject("f"));
+  T.CheckCall(T.Val("6x"), T.NewObject("({d:'x'})"), T.NewObject("f"));
 }
 
 
 TEST(ClassOf) {
-  FLAG_turbo_inlining_intrinsics = true;
-  FLAG_turbo_deoptimization = true;
   FunctionTester T("(function(a) { return %_ClassOf(a); })", flags);
 
   T.CheckCall(T.Val("Function"), T.NewObject("(function() {})"));
@@ -132,9 +34,121 @@
 }
 
 
+#define COUNTER_NAME "hurz"
+
+static int* LookupCounter(const char* name) {
+  static int counter = 1234;
+  return strcmp(name, COUNTER_NAME) == 0 ? &counter : nullptr;
+}
+
+
+TEST(IncrementStatsCounter) {
+  FLAG_native_code_counters = true;
+  reinterpret_cast<v8::Isolate*>(CcTest::InitIsolateOnce())
+      ->SetCounterFunction(LookupCounter);
+  FunctionTester T(
+      "(function() { %_IncrementStatsCounter('" COUNTER_NAME "'); })", flags);
+  StatsCounter counter(T.main_isolate(), COUNTER_NAME);
+  if (!counter.Enabled()) return;
+
+  int old_value = *counter.GetInternalPointer();
+  T.CheckCall(T.undefined());
+  CHECK_EQ(old_value + 1, *counter.GetInternalPointer());
+}
+
+#undef COUNTER_NAME
+
+
+TEST(IsArray) {
+  FunctionTester T("(function(a) { return %_IsArray(a); })", flags);
+
+  T.CheckFalse(T.NewObject("new Date()"));
+  T.CheckFalse(T.NewObject("(function() {})"));
+  T.CheckTrue(T.NewObject("([1])"));
+  T.CheckFalse(T.NewObject("({})"));
+  T.CheckFalse(T.NewObject("(/x/)"));
+  T.CheckFalse(T.undefined());
+  T.CheckFalse(T.null());
+  T.CheckFalse(T.Val("x"));
+  T.CheckFalse(T.Val(1));
+}
+
+
+TEST(IsDate) {
+  FunctionTester T("(function(a) { return %_IsDate(a); })", flags);
+
+  T.CheckTrue(T.NewObject("new Date()"));
+  T.CheckFalse(T.NewObject("(function() {})"));
+  T.CheckFalse(T.NewObject("([1])"));
+  T.CheckFalse(T.NewObject("({})"));
+  T.CheckFalse(T.NewObject("(/x/)"));
+  T.CheckFalse(T.undefined());
+  T.CheckFalse(T.null());
+  T.CheckFalse(T.Val("x"));
+  T.CheckFalse(T.Val(1));
+}
+
+
+TEST(IsFunction) {
+  FunctionTester T("(function(a) { return %_IsFunction(a); })", flags);
+
+  T.CheckFalse(T.NewObject("new Date()"));
+  T.CheckTrue(T.NewObject("(function() {})"));
+  T.CheckFalse(T.NewObject("([1])"));
+  T.CheckFalse(T.NewObject("({})"));
+  T.CheckFalse(T.NewObject("(/x/)"));
+  T.CheckFalse(T.undefined());
+  T.CheckFalse(T.null());
+  T.CheckFalse(T.Val("x"));
+  T.CheckFalse(T.Val(1));
+}
+
+
+TEST(IsMinusZero) {
+  FunctionTester T("(function(a) { return %_IsMinusZero(a); })", flags);
+
+  T.CheckFalse(T.Val(1));
+  T.CheckFalse(T.Val(1.1));
+  T.CheckTrue(T.Val(-0.0));
+  T.CheckFalse(T.Val(-2));
+  T.CheckFalse(T.Val(-2.3));
+  T.CheckFalse(T.undefined());
+}
+
+
+TEST(IsRegExp) {
+  FunctionTester T("(function(a) { return %_IsRegExp(a); })", flags);
+
+  T.CheckFalse(T.NewObject("new Date()"));
+  T.CheckFalse(T.NewObject("(function() {})"));
+  T.CheckFalse(T.NewObject("([1])"));
+  T.CheckFalse(T.NewObject("({})"));
+  T.CheckTrue(T.NewObject("(/x/)"));
+  T.CheckFalse(T.undefined());
+  T.CheckFalse(T.null());
+  T.CheckFalse(T.Val("x"));
+  T.CheckFalse(T.Val(1));
+}
+
+
+TEST(IsSmi) {
+  FunctionTester T("(function(a) { return %_IsSmi(a); })", flags);
+
+  T.CheckFalse(T.NewObject("new Date()"));
+  T.CheckFalse(T.NewObject("(function() {})"));
+  T.CheckFalse(T.NewObject("([1])"));
+  T.CheckFalse(T.NewObject("({})"));
+  T.CheckFalse(T.NewObject("(/x/)"));
+  T.CheckFalse(T.undefined());
+  T.CheckTrue(T.Val(1));
+  T.CheckFalse(T.Val(1.1));
+  T.CheckFalse(T.Val(-0.0));
+  T.CheckTrue(T.Val(-2));
+  T.CheckFalse(T.Val(-2.3));
+}
+
+
 TEST(ObjectEquals) {
-  FLAG_turbo_inlining_intrinsics = true;
-  FLAG_turbo_deoptimization = true;
   FunctionTester T("(function(a,b) { return %_ObjectEquals(a,b); })", flags);
   CompileRun("var o = {}");
 
@@ -147,21 +161,38 @@
 }
 
 
-TEST(ValueOf) {
-  FLAG_turbo_inlining_intrinsics = true;
-  FLAG_turbo_deoptimization = true;
-  FunctionTester T("(function(a) { return %_ValueOf(a); })", flags);
+TEST(OneByteSeqStringGetChar) {
+  FunctionTester T("(function(a,b) { return %_OneByteSeqStringGetChar(a,b); })",
+                   flags);
 
-  T.CheckCall(T.Val("a"), T.Val("a"));
-  T.CheckCall(T.Val("b"), T.NewObject("(new String('b'))"));
-  T.CheckCall(T.Val(123), T.Val(123));
-  T.CheckCall(T.Val(456), T.NewObject("(new Number(456))"));
+  Handle<SeqOneByteString> string =
+      T.main_isolate()->factory()->NewRawOneByteString(3).ToHandleChecked();
+  string->SeqOneByteStringSet(0, 'b');
+  string->SeqOneByteStringSet(1, 'a');
+  string->SeqOneByteStringSet(2, 'r');
+  T.CheckCall(T.Val('b'), string, T.Val(0.0));
+  T.CheckCall(T.Val('a'), string, T.Val(1));
+  T.CheckCall(T.Val('r'), string, T.Val(2));
+}
+
+
+TEST(OneByteSeqStringSetChar) {
+  FunctionTester T("(function(a,b) { %_OneByteSeqStringSetChar(a,88,b); })",
+                   flags);
+
+  Handle<SeqOneByteString> string =
+      T.main_isolate()->factory()->NewRawOneByteString(3).ToHandleChecked();
+  string->SeqOneByteStringSet(0, 'b');
+  string->SeqOneByteStringSet(1, 'a');
+  string->SeqOneByteStringSet(2, 'r');
+  T.Call(T.Val(1), string);
+  CHECK_EQ('b', string->SeqOneByteStringGet(0));
+  CHECK_EQ('X', string->SeqOneByteStringGet(1));
+  CHECK_EQ('r', string->SeqOneByteStringGet(2));
 }
 
 
 TEST(SetValueOf) {
-  FLAG_turbo_inlining_intrinsics = true;
-  FLAG_turbo_deoptimization = true;
   FunctionTester T("(function(a,b) { return %_SetValueOf(a,b); })", flags);
 
   T.CheckCall(T.Val("a"), T.NewObject("(new String)"), T.Val("a"));
@@ -170,20 +201,16 @@
 }
 
 
-TEST(StringCharFromCode) {
-  FLAG_turbo_inlining_intrinsics = true;
-  FLAG_turbo_deoptimization = true;
-  FunctionTester T("(function(a) { return %_StringCharFromCode(a); })", flags);
+TEST(StringAdd) {
+  FunctionTester T("(function(a,b) { return %_StringAdd(a,b); })", flags);
 
-  T.CheckCall(T.Val("a"), T.Val(97));
-  T.CheckCall(T.Val("\xE2\x9D\x8A"), T.Val(0x274A));
-  T.CheckCall(T.Val(""), T.undefined());
+  T.CheckCall(T.Val("aaabbb"), T.Val("aaa"), T.Val("bbb"));
+  T.CheckCall(T.Val("aaa"), T.Val("aaa"), T.Val(""));
+  T.CheckCall(T.Val("bbb"), T.Val(""), T.Val("bbb"));
 }
 
 
 TEST(StringCharAt) {
-  FLAG_turbo_inlining_intrinsics = true;
-  FLAG_turbo_deoptimization = true;
   FunctionTester T("(function(a,b) { return %_StringCharAt(a,b); })", flags);
 
   T.CheckCall(T.Val("e"), T.Val("huge fan!"), T.Val(3));
@@ -193,8 +220,6 @@
 
 
 TEST(StringCharCodeAt) {
-  FLAG_turbo_inlining_intrinsics = true;
-  FLAG_turbo_deoptimization = true;
   FunctionTester T("(function(a,b) { return %_StringCharCodeAt(a,b); })",
                    flags);
 
@@ -204,31 +229,16 @@
 }
 
 
-TEST(StringAdd) {
-  FLAG_turbo_inlining_intrinsics = true;
-  FLAG_turbo_deoptimization = true;
-  FunctionTester T("(function(a,b) { return %_StringAdd(a,b); })", flags);
+TEST(StringCharFromCode) {
+  FunctionTester T("(function(a) { return %_StringCharFromCode(a); })", flags);
 
-  T.CheckCall(T.Val("aaabbb"), T.Val("aaa"), T.Val("bbb"));
-  T.CheckCall(T.Val("aaa"), T.Val("aaa"), T.Val(""));
-  T.CheckCall(T.Val("bbb"), T.Val(""), T.Val("bbb"));
-}
-
-
-TEST(StringSubString) {
-  FLAG_turbo_inlining_intrinsics = true;
-  FLAG_turbo_deoptimization = true;
-  FunctionTester T("(function(a,b) { return %_SubString(a,b,b+3); })", flags);
-
-  T.CheckCall(T.Val("aaa"), T.Val("aaabbb"), T.Val(0.0));
-  T.CheckCall(T.Val("abb"), T.Val("aaabbb"), T.Val(2));
-  T.CheckCall(T.Val("aaa"), T.Val("aaa"), T.Val(0.0));
+  T.CheckCall(T.Val("a"), T.Val(97));
+  T.CheckCall(T.Val("\xE2\x9D\x8A"), T.Val(0x274A));
+  T.CheckCall(T.Val(""), T.undefined());
 }
 
 
 TEST(StringCompare) {
-  FLAG_turbo_inlining_intrinsics = true;
-  FLAG_turbo_deoptimization = true;
   FunctionTester T("(function(a,b) { return %_StringCompare(a,b); })", flags);
 
   T.CheckCall(T.Val(-1), T.Val("aaa"), T.Val("bbb"));
@@ -237,13 +247,55 @@
 }
 
 
-TEST(CallFunction) {
-  FLAG_turbo_inlining_intrinsics = true;
-  FLAG_turbo_deoptimization = true;
-  FunctionTester T("(function(a,b) { return %_CallFunction(a, 1, 2, 3, b); })",
-                   flags);
-  CompileRun("function f(a,b,c) { return a + b + c + this.d; }");
+TEST(SubString) {
+  FunctionTester T("(function(a,b) { return %_SubString(a,b,b+3); })", flags);
 
-  T.CheckCall(T.Val(129), T.NewObject("({d:123})"), T.NewObject("f"));
-  T.CheckCall(T.Val("6x"), T.NewObject("({d:'x'})"), T.NewObject("f"));
+  T.CheckCall(T.Val("aaa"), T.Val("aaabbb"), T.Val(0.0));
+  T.CheckCall(T.Val("abb"), T.Val("aaabbb"), T.Val(2));
+  T.CheckCall(T.Val("aaa"), T.Val("aaa"), T.Val(0.0));
 }
+
+
+TEST(TwoByteSeqStringGetChar) {
+  FunctionTester T("(function(a,b) { return %_TwoByteSeqStringGetChar(a,b); })",
+                   flags);
+
+  Handle<SeqTwoByteString> string =
+      T.main_isolate()->factory()->NewRawTwoByteString(3).ToHandleChecked();
+  string->SeqTwoByteStringSet(0, 'b');
+  string->SeqTwoByteStringSet(1, 'a');
+  string->SeqTwoByteStringSet(2, 'r');
+  T.CheckCall(T.Val('b'), string, T.Val(0.0));
+  T.CheckCall(T.Val('a'), string, T.Val(1));
+  T.CheckCall(T.Val('r'), string, T.Val(2));
+}
+
+
+TEST(TwoByteSeqStringSetChar) {
+  FunctionTester T("(function(a,b) { %_TwoByteSeqStringSetChar(a,88,b); })",
+                   flags);
+
+  Handle<SeqTwoByteString> string =
+      T.main_isolate()->factory()->NewRawTwoByteString(3).ToHandleChecked();
+  string->SeqTwoByteStringSet(0, 'b');
+  string->SeqTwoByteStringSet(1, 'a');
+  string->SeqTwoByteStringSet(2, 'r');
+  T.Call(T.Val(1), string);
+  CHECK_EQ('b', string->SeqTwoByteStringGet(0));
+  CHECK_EQ('X', string->SeqTwoByteStringGet(1));
+  CHECK_EQ('r', string->SeqTwoByteStringGet(2));
+}
+
+
+TEST(ValueOf) {
+  FunctionTester T("(function(a) { return %_ValueOf(a); })", flags);
+
+  T.CheckCall(T.Val("a"), T.Val("a"));
+  T.CheckCall(T.Val("b"), T.NewObject("(new String('b'))"));
+  T.CheckCall(T.Val(123), T.Val(123));
+  T.CheckCall(T.Val(456), T.NewObject("(new Number(456))"));
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/test/cctest/compiler/test-run-jsbranches.cc b/test/cctest/compiler/test-run-jsbranches.cc
index 7a4a0b3..613528d 100644
--- a/test/cctest/compiler/test-run-jsbranches.cc
+++ b/test/cctest/compiler/test-run-jsbranches.cc
@@ -2,12 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "src/v8.h"
-
 #include "test/cctest/compiler/function-tester.h"
 
-using namespace v8::internal;
-using namespace v8::internal::compiler;
+namespace v8 {
+namespace internal {
+namespace compiler {
 
 TEST(Conditional) {
   FunctionTester T("(function(a) { return a ? 23 : 42; })");
@@ -168,6 +167,33 @@
 }
 
 
+TEST(ForOfContinueStatement) {
+  const char* src =
+      "(function(a,b) {"
+      "  var r = '-';"
+      "  for (var x of a) {"
+      "    r += x + '-';"
+      "    if (b) continue;"
+      "    r += 'X-';"
+      "  }"
+      "  return r;"
+      "})";
+  FunctionTester T(src);
+
+  CompileRun(
+      "function wrap(v) {"
+      "  var iterable = {};"
+      "  function next() { return { done:!v.length, value:v.shift() }; };"
+      "  iterable[Symbol.iterator] = function() { return { next:next }; };"
+      "  return iterable;"
+      "}");
+
+  T.CheckCall(T.Val("-"), T.NewObject("wrap([])"), T.true_value());
+  T.CheckCall(T.Val("-1-2-"), T.NewObject("wrap([1,2])"), T.true_value());
+  T.CheckCall(T.Val("-1-X-2-X-"), T.NewObject("wrap([1,2])"), T.false_value());
+}
+
+
 TEST(SwitchStatement) {
   const char* src =
       "(function(a,b) {"
@@ -355,3 +381,7 @@
   T.CheckCall(T.Val(8126.1), T.Val(0.0), T.Val(8126.1));
   T.CheckCall(T.Val(1123.1), T.Val(0.0), T.Val(1123.1));
 }
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/test/cctest/compiler/test-run-jscalls.cc b/test/cctest/compiler/test-run-jscalls.cc
index dec7194..474453d 100644
--- a/test/cctest/compiler/test-run-jscalls.cc
+++ b/test/cctest/compiler/test-run-jscalls.cc
@@ -2,12 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "src/v8.h"
-
 #include "test/cctest/compiler/function-tester.h"
 
-using namespace v8::internal;
-using namespace v8::internal::compiler;
+namespace v8 {
+namespace internal {
+namespace compiler {
 
 TEST(SimpleCall) {
   FunctionTester T("(function(foo,a) { return foo(a); })");
@@ -132,46 +131,18 @@
 
 
 // TODO(titzer): factor these out into test-runtime-calls.cc
-TEST(RuntimeCallCPP1) {
-  FLAG_allow_natives_syntax = true;
-  FunctionTester T("(function(a) { return %ToBool(a); })");
-
-  T.CheckCall(T.true_value(), T.Val(23), T.undefined());
-  T.CheckCall(T.true_value(), T.Val(4.2), T.undefined());
-  T.CheckCall(T.true_value(), T.Val("str"), T.undefined());
-  T.CheckCall(T.true_value(), T.true_value(), T.undefined());
-  T.CheckCall(T.false_value(), T.false_value(), T.undefined());
-  T.CheckCall(T.false_value(), T.undefined(), T.undefined());
-  T.CheckCall(T.false_value(), T.Val(0.0), T.undefined());
-}
-
-
 TEST(RuntimeCallCPP2) {
   FLAG_allow_natives_syntax = true;
-  FunctionTester T("(function(a,b) { return %NumberAdd(a, b); })");
+  FunctionTester T("(function(a,b) { return %NumberImul(a, b); })");
 
-  T.CheckCall(T.Val(65), T.Val(42), T.Val(23));
-  T.CheckCall(T.Val(19), T.Val(42), T.Val(-23));
-  T.CheckCall(T.Val(6.5), T.Val(4.2), T.Val(2.3));
-}
-
-
-TEST(RuntimeCallJS) {
-  FLAG_allow_natives_syntax = true;
-  FunctionTester T("(function(a) { return %ToString(a); })");
-
-  T.CheckCall(T.Val("23"), T.Val(23), T.undefined());
-  T.CheckCall(T.Val("4.2"), T.Val(4.2), T.undefined());
-  T.CheckCall(T.Val("str"), T.Val("str"), T.undefined());
-  T.CheckCall(T.Val("true"), T.true_value(), T.undefined());
-  T.CheckCall(T.Val("false"), T.false_value(), T.undefined());
-  T.CheckCall(T.Val("undefined"), T.undefined(), T.undefined());
+  T.CheckCall(T.Val(2730), T.Val(42), T.Val(65));
+  T.CheckCall(T.Val(798), T.Val(42), T.Val(19));
 }
 
 
 TEST(RuntimeCallInline) {
   FLAG_allow_natives_syntax = true;
-  FunctionTester T("(function(a) { return %_IsObject(a); })");
+  FunctionTester T("(function(a) { return %_IsJSReceiver(a); })");
 
   T.CheckCall(T.false_value(), T.Val(23), T.undefined());
   T.CheckCall(T.false_value(), T.Val(4.2), T.undefined());
@@ -184,26 +155,6 @@
 }
 
 
-TEST(RuntimeCallBooleanize) {
-  // TODO(turbofan): %Booleanize will disappear, don't hesitate to remove this
-  // test case, two-argument case is covered by the above test already.
-  FLAG_allow_natives_syntax = true;
-  FunctionTester T("(function(a,b) { return %Booleanize(a, b); })");
-
-  T.CheckCall(T.true_value(), T.Val(-1), T.Val(Token::LT));
-  T.CheckCall(T.false_value(), T.Val(-1), T.Val(Token::EQ));
-  T.CheckCall(T.false_value(), T.Val(-1), T.Val(Token::GT));
-
-  T.CheckCall(T.false_value(), T.Val(0.0), T.Val(Token::LT));
-  T.CheckCall(T.true_value(), T.Val(0.0), T.Val(Token::EQ));
-  T.CheckCall(T.false_value(), T.Val(0.0), T.Val(Token::GT));
-
-  T.CheckCall(T.false_value(), T.Val(1), T.Val(Token::LT));
-  T.CheckCall(T.false_value(), T.Val(1), T.Val(Token::EQ));
-  T.CheckCall(T.true_value(), T.Val(1), T.Val(Token::GT));
-}
-
-
 TEST(EvalCall) {
   FunctionTester T("(function(a,b) { return eval(a); })");
   Handle<JSObject> g(T.function->context()->global_object()->global_proxy());
@@ -262,7 +213,10 @@
   i::Handle<i::Object> ofun = v8::Utils::OpenHandle(*value);
   i::Handle<i::JSFunction> jsfun = Handle<JSFunction>::cast(ofun);
   jsfun->set_code(T.function->code());
-  context->Global()->Set(v8_str("foo"), v8::Utils::ToLocal(jsfun));
+  jsfun->set_shared(T.function->shared());
+  CHECK(context->Global()
+            ->Set(context, v8_str("foo"), v8::Utils::CallableToLocal(jsfun))
+            .FromJust());
   CompileRun("var x = 24;");
   ExpectInt32("foo();", 24);
 }
@@ -283,7 +237,14 @@
   i::Handle<i::Object> ofun = v8::Utils::OpenHandle(*value);
   i::Handle<i::JSFunction> jsfun = Handle<JSFunction>::cast(ofun);
   jsfun->set_code(T.function->code());
-  context->Global()->Set(v8_str("foo"), v8::Utils::ToLocal(jsfun));
+  jsfun->set_shared(T.function->shared());
+  CHECK(context->Global()
+            ->Set(context, v8_str("foo"), v8::Utils::CallableToLocal(jsfun))
+            .FromJust());
   CompileRun("var x = 24;");
   ExpectObject("foo()", context->Global());
 }
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/test/cctest/compiler/test-run-jsexceptions.cc b/test/cctest/compiler/test-run-jsexceptions.cc
index 0712ab6..37b2a2d 100644
--- a/test/cctest/compiler/test-run-jsexceptions.cc
+++ b/test/cctest/compiler/test-run-jsexceptions.cc
@@ -2,12 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "src/v8.h"
-
 #include "test/cctest/compiler/function-tester.h"
 
-using namespace v8::internal;
-using namespace v8::internal::compiler;
+namespace v8 {
+namespace internal {
+namespace compiler {
 
 TEST(Throw) {
   FunctionTester T("(function(a,b) { if (a) { throw b; } else { return b; }})");
@@ -17,7 +16,7 @@
 }
 
 
-TEST(ThrowSourcePosition) {
+TEST(ThrowMessagePosition) {
   static const char* src =
       "(function(a, b) {        \n"
       "  if (a == 1) throw 1;   \n"
@@ -26,20 +25,258 @@
       "  throw 4;               \n"
       "})                       ";
   FunctionTester T(src);
-  v8::Handle<v8::Message> message;
+  v8::Local<v8::Message> message;
+  v8::Local<v8::Context> context = CcTest::isolate()->GetCurrentContext();
 
   message = T.CheckThrowsReturnMessage(T.Val(1), T.undefined());
-  CHECK(!message.IsEmpty());
-  CHECK_EQ(2, message->GetLineNumber());
+  CHECK_EQ(2, message->GetLineNumber(context).FromMaybe(-1));
   CHECK_EQ(40, message->GetStartPosition());
 
   message = T.CheckThrowsReturnMessage(T.Val(2), T.undefined());
-  CHECK(!message.IsEmpty());
-  CHECK_EQ(3, message->GetLineNumber());
+  CHECK_EQ(3, message->GetLineNumber(context).FromMaybe(-1));
   CHECK_EQ(67, message->GetStartPosition());
 
   message = T.CheckThrowsReturnMessage(T.Val(3), T.undefined());
-  CHECK(!message.IsEmpty());
-  CHECK_EQ(4, message->GetLineNumber());
+  CHECK_EQ(4, message->GetLineNumber(context).FromMaybe(-1));
   CHECK_EQ(95, message->GetStartPosition());
 }
+
+
+TEST(ThrowMessageDirectly) {
+  static const char* src =
+      "(function(a, b) {"
+      "  if (a) { throw b; } else { throw new Error(b); }"
+      "})";
+  FunctionTester T(src);
+  v8::Local<v8::Message> message;
+  v8::Local<v8::Context> context = CcTest::isolate()->GetCurrentContext();
+  v8::Maybe<bool> t = v8::Just(true);
+
+  message = T.CheckThrowsReturnMessage(T.false_value(), T.Val("Wat?"));
+  CHECK(t == message->Get()->Equals(context, v8_str("Uncaught Error: Wat?")));
+
+  message = T.CheckThrowsReturnMessage(T.true_value(), T.Val("Kaboom!"));
+  CHECK(t == message->Get()->Equals(context, v8_str("Uncaught Kaboom!")));
+}
+
+
+TEST(ThrowMessageIndirectly) {
+  i::FLAG_turbo_try_finally = true;
+  static const char* src =
+      "(function(a, b) {"
+      "  try {"
+      "    if (a) { throw b; } else { throw new Error(b); }"
+      "  } finally {"
+      "    try { throw 'clobber'; } catch (e) { 'unclobber'; }"
+      "  }"
+      "})";
+  FunctionTester T(src);
+  v8::Local<v8::Message> message;
+  v8::Local<v8::Context> context = CcTest::isolate()->GetCurrentContext();
+  v8::Maybe<bool> t = v8::Just(true);
+
+  message = T.CheckThrowsReturnMessage(T.false_value(), T.Val("Wat?"));
+  CHECK(t == message->Get()->Equals(context, v8_str("Uncaught Error: Wat?")));
+
+  message = T.CheckThrowsReturnMessage(T.true_value(), T.Val("Kaboom!"));
+  CHECK(t == message->Get()->Equals(context, v8_str("Uncaught Kaboom!")));
+}
+
+
+TEST(Catch) {
+  const char* src =
+      "(function(a,b) {"
+      "  var r = '-';"
+      "  try {"
+      "    r += 'A-';"
+      "    throw 'B-';"
+      "  } catch (e) {"
+      "    r += e;"
+      "  }"
+      "  return r;"
+      "})";
+  FunctionTester T(src);
+
+  T.CheckCall(T.Val("-A-B-"));
+}
+
+
+TEST(CatchNested) {
+  const char* src =
+      "(function(a,b) {"
+      "  var r = '-';"
+      "  try {"
+      "    r += 'A-';"
+      "    throw 'C-';"
+      "  } catch (e) {"
+      "    try {"
+      "      throw 'B-';"
+      "    } catch (e) {"
+      "      r += e;"
+      "    }"
+      "    r += e;"
+      "  }"
+      "  return r;"
+      "})";
+  FunctionTester T(src);
+
+  T.CheckCall(T.Val("-A-B-C-"));
+}
+
+
+TEST(CatchBreak) {
+  const char* src =
+      "(function(a,b) {"
+      "  var r = '-';"
+      "  L: try {"
+      "    r += 'A-';"
+      "    if (a) break L;"
+      "    r += 'B-';"
+      "    throw 'C-';"
+      "  } catch (e) {"
+      "    if (b) break L;"
+      "    r += e;"
+      "  }"
+      "  r += 'D-';"
+      "  return r;"
+      "})";
+  FunctionTester T(src);
+
+  T.CheckCall(T.Val("-A-D-"), T.true_value(), T.false_value());
+  T.CheckCall(T.Val("-A-B-D-"), T.false_value(), T.true_value());
+  T.CheckCall(T.Val("-A-B-C-D-"), T.false_value(), T.false_value());
+}
+
+
+TEST(CatchCall) {
+  const char* src =
+      "(function(fun) {"
+      "  var r = '-';"
+      "  try {"
+      "    r += 'A-';"
+      "    return r + 'B-' + fun();"
+      "  } catch (e) {"
+      "    r += e;"
+      "  }"
+      "  return r;"
+      "})";
+  FunctionTester T(src);
+
+  CompileRun("function thrower() { throw 'T-'; }");
+  T.CheckCall(T.Val("-A-T-"), T.NewFunction("thrower"));
+  CompileRun("function returner() { return 'R-'; }");
+  T.CheckCall(T.Val("-A-B-R-"), T.NewFunction("returner"));
+}
+
+
+TEST(Finally) {
+  i::FLAG_turbo_try_finally = true;
+  const char* src =
+      "(function(a,b) {"
+      "  var r = '-';"
+      "  try {"
+      "    r += 'A-';"
+      "  } finally {"
+      "    r += 'B-';"
+      "  }"
+      "  return r;"
+      "})";
+  FunctionTester T(src);
+
+  T.CheckCall(T.Val("-A-B-"));
+}
+
+
+TEST(FinallyBreak) {
+  i::FLAG_turbo_try_finally = true;
+  const char* src =
+      "(function(a,b) {"
+      "  var r = '-';"
+      "  L: try {"
+      "    r += 'A-';"
+      "    if (a) return r;"
+      "    r += 'B-';"
+      "    if (b) break L;"
+      "    r += 'C-';"
+      "  } finally {"
+      "    r += 'D-';"
+      "  }"
+      "  return r;"
+      "})";
+  FunctionTester T(src);
+
+  T.CheckCall(T.Val("-A-"), T.true_value(), T.false_value());
+  T.CheckCall(T.Val("-A-B-D-"), T.false_value(), T.true_value());
+  T.CheckCall(T.Val("-A-B-C-D-"), T.false_value(), T.false_value());
+}
+
+
+TEST(DeoptTry) {
+  const char* src =
+      "(function f(a) {"
+      "  try {"
+      "    %DeoptimizeFunction(f);"
+      "    throw a;"
+      "  } catch (e) {"
+      "    return e + 1;"
+      "  }"
+      "})";
+  FunctionTester T(src);
+
+  T.CheckCall(T.Val(2), T.Val(1));
+}
+
+
+TEST(DeoptCatch) {
+  const char* src =
+      "(function f(a) {"
+      "  try {"
+      "    throw a;"
+      "  } catch (e) {"
+      "    %DeoptimizeFunction(f);"
+      "    return e + 1;"
+      "  }"
+      "})";
+  FunctionTester T(src);
+
+  T.CheckCall(T.Val(2), T.Val(1));
+}
+
+
+TEST(DeoptFinallyReturn) {
+  i::FLAG_turbo_try_finally = true;
+  const char* src =
+      "(function f(a) {"
+      "  try {"
+      "    throw a;"
+      "  } finally {"
+      "    %DeoptimizeFunction(f);"
+      "    return a + 1;"
+      "  }"
+      "})";
+  FunctionTester T(src);
+
+  T.CheckCall(T.Val(2), T.Val(1));
+}
+
+
+TEST(DeoptFinallyReThrow) {
+  i::FLAG_turbo_try_finally = true;
+  const char* src =
+      "(function f(a) {"
+      "  try {"
+      "    throw a;"
+      "  } finally {"
+      "    %DeoptimizeFunction(f);"
+      "  }"
+      "})";
+  FunctionTester T(src);
+
+#if 0  // TODO(mstarzinger): Enable once we can.
+  T.CheckThrows(T.NewObject("new Error"), T.Val(1));
+#endif
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/test/cctest/compiler/test-run-jsobjects.cc b/test/cctest/compiler/test-run-jsobjects.cc
new file mode 100644
index 0000000..4bf10ca
--- /dev/null
+++ b/test/cctest/compiler/test-run-jsobjects.cc
@@ -0,0 +1,51 @@
+// Copyright 2015 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "test/cctest/compiler/function-tester.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+TEST(ArgumentsMapped) {
+  FunctionTester T("(function(a) { return arguments; })");
+
+  Handle<Object> arguments;
+  T.Call(T.Val(19), T.Val(23), T.Val(42), T.Val(65)).ToHandle(&arguments);
+  CHECK(arguments->IsJSObject() && !arguments->IsJSArray());
+  CHECK(JSObject::cast(*arguments)->HasSloppyArgumentsElements());
+  Handle<String> l = T.isolate->factory()->length_string();
+  Handle<Object> length = JSObject::GetProperty(arguments, l).ToHandleChecked();
+  CHECK_EQ(4, length->Number());
+}
+
+
+TEST(ArgumentsUnmapped) {
+  FunctionTester T("(function(a) { 'use strict'; return arguments; })");
+
+  Handle<Object> arguments;
+  T.Call(T.Val(19), T.Val(23), T.Val(42), T.Val(65)).ToHandle(&arguments);
+  CHECK(arguments->IsJSObject() && !arguments->IsJSArray());
+  CHECK(!JSObject::cast(*arguments)->HasSloppyArgumentsElements());
+  Handle<String> l = T.isolate->factory()->length_string();
+  Handle<Object> length = JSObject::GetProperty(arguments, l).ToHandleChecked();
+  CHECK_EQ(4, length->Number());
+}
+
+
+TEST(ArgumentsRest) {
+  FunctionTester T("(function(a, ...args) { return args; })");
+
+  Handle<Object> arguments;
+  T.Call(T.Val(19), T.Val(23), T.Val(42), T.Val(65)).ToHandle(&arguments);
+  CHECK(arguments->IsJSObject() && arguments->IsJSArray());
+  CHECK(!JSObject::cast(*arguments)->HasSloppyArgumentsElements());
+  Handle<String> l = T.isolate->factory()->length_string();
+  Handle<Object> length = JSObject::GetProperty(arguments, l).ToHandleChecked();
+  CHECK_EQ(3, length->Number());
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/test/cctest/compiler/test-run-jsops.cc b/test/cctest/compiler/test-run-jsops.cc
index eb39760..9a2c467 100644
--- a/test/cctest/compiler/test-run-jsops.cc
+++ b/test/cctest/compiler/test-run-jsops.cc
@@ -2,12 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "src/v8.h"
-
 #include "test/cctest/compiler/function-tester.h"
 
-using namespace v8::internal;
-using namespace v8::internal::compiler;
+namespace v8 {
+namespace internal {
+namespace compiler {
 
 TEST(BinopAdd) {
   FunctionTester T("(function(a,b) { return a + b; })");
@@ -212,7 +211,7 @@
 }
 
 
-TEST(BinopLessThanEqual) {
+TEST(BinopLessThanOrEqual) {
   FunctionTester T("(function(a,b) { return a <= b; })");
 
   T.CheckTrue(7, 8);
@@ -396,6 +395,7 @@
 
 
 TEST(GlobalStoreSloppy) {
+  FLAG_legacy_const = true;
   FunctionTester T("(function(a,b) { g = a + b; return g; })");
 
   T.CheckCall(T.Val(33), T.Val(22), T.Val(11));
@@ -451,7 +451,6 @@
 
 
 TEST(BlockLoadStore) {
-  FLAG_harmony_scoping = true;
   FunctionTester T("(function(a) { 'use strict'; { let x = a+a; return x; }})");
 
   T.CheckCall(T.Val(46), T.Val(23));
@@ -460,7 +459,6 @@
 
 
 TEST(BlockLoadStoreNested) {
-  FLAG_harmony_scoping = true;
   const char* src =
       "(function(a,b) {"
       "'use strict';"
@@ -522,3 +520,26 @@
   T.CheckTrue(T.Val("abc"));
   T.CheckFalse(T.Val("xyz"));
 }
+
+
+TEST(ClassLiteral) {
+  FLAG_harmony_sloppy = true;
+  const char* src =
+      "(function(a,b) {"
+      "  class C {"
+      "    x() { return a; }"
+      "    static y() { return b; }"
+      "    get z() { return 0; }"
+      "    constructor() {}"
+      "  }"
+      "  return new C().x() + C.y();"
+      "})";
+  FunctionTester T(src);
+
+  T.CheckCall(T.Val(65), T.Val(23), T.Val(42));
+  T.CheckCall(T.Val("ab"), T.Val("a"), T.Val("b"));
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/test/cctest/compiler/test-run-machops.cc b/test/cctest/compiler/test-run-machops.cc
index 974d4ce..11a3582 100644
--- a/test/cctest/compiler/test-run-machops.cc
+++ b/test/cctest/compiler/test-run-machops.cc
@@ -1,28 +1,25 @@
-// Copyright 2014 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
+// Copyright 2014 the V8 project authors. All rights reserved. Use of this
+// source code is governed by a BSD-style license that can be found in the
+// LICENSE file.
 
 #include <cmath>
 #include <functional>
 #include <limits>
 
 #include "src/base/bits.h"
+#include "src/base/utils/random-number-generator.h"
 #include "src/codegen.h"
 #include "test/cctest/cctest.h"
 #include "test/cctest/compiler/codegen-tester.h"
+#include "test/cctest/compiler/graph-builder-tester.h"
 #include "test/cctest/compiler/value-helper.h"
 
-#if V8_TURBOFAN_TARGET
-
 using namespace v8::base;
 
-#define CHECK_UINT32_EQ(x, y) \
-  CHECK_EQ(static_cast<int32_t>(x), static_cast<int32_t>(y))
+namespace v8 {
+namespace internal {
+namespace compiler {
 
-using namespace v8::internal;
-using namespace v8::internal::compiler;
-
-typedef RawMachineAssembler::Label MLabel;
 
 TEST(RunInt32Add) {
   RawMachineAssemblerTester<int32_t> m;
@@ -32,6 +29,278 @@
 }
 
 
+TEST(RunWord32Ctz) {
+  BufferedRawMachineAssemblerTester<int32_t> m(MachineType::Uint32());
+  if (!m.machine()->Word32Ctz().IsSupported()) {
+    // We can only test the operator if it exists on the testing platform.
+    return;
+  }
+  m.Return(m.AddNode(m.machine()->Word32Ctz().op(), m.Parameter(0)));
+
+  CHECK_EQ(32, m.Call(uint32_t(0x00000000)));
+  CHECK_EQ(31, m.Call(uint32_t(0x80000000)));
+  CHECK_EQ(30, m.Call(uint32_t(0x40000000)));
+  CHECK_EQ(29, m.Call(uint32_t(0x20000000)));
+  CHECK_EQ(28, m.Call(uint32_t(0x10000000)));
+  CHECK_EQ(27, m.Call(uint32_t(0xa8000000)));
+  CHECK_EQ(26, m.Call(uint32_t(0xf4000000)));
+  CHECK_EQ(25, m.Call(uint32_t(0x62000000)));
+  CHECK_EQ(24, m.Call(uint32_t(0x91000000)));
+  CHECK_EQ(23, m.Call(uint32_t(0xcd800000)));
+  CHECK_EQ(22, m.Call(uint32_t(0x09400000)));
+  CHECK_EQ(21, m.Call(uint32_t(0xaf200000)));
+  CHECK_EQ(20, m.Call(uint32_t(0xac100000)));
+  CHECK_EQ(19, m.Call(uint32_t(0xe0b80000)));
+  CHECK_EQ(18, m.Call(uint32_t(0x9ce40000)));
+  CHECK_EQ(17, m.Call(uint32_t(0xc7920000)));
+  CHECK_EQ(16, m.Call(uint32_t(0xb8f10000)));
+  CHECK_EQ(15, m.Call(uint32_t(0x3b9f8000)));
+  CHECK_EQ(14, m.Call(uint32_t(0xdb4c4000)));
+  CHECK_EQ(13, m.Call(uint32_t(0xe9a32000)));
+  CHECK_EQ(12, m.Call(uint32_t(0xfca61000)));
+  CHECK_EQ(11, m.Call(uint32_t(0x6c8a7800)));
+  CHECK_EQ(10, m.Call(uint32_t(0x8ce5a400)));
+  CHECK_EQ(9, m.Call(uint32_t(0xcb7d0200)));
+  CHECK_EQ(8, m.Call(uint32_t(0xcb4dc100)));
+  CHECK_EQ(7, m.Call(uint32_t(0xdfbec580)));
+  CHECK_EQ(6, m.Call(uint32_t(0x27a9db40)));
+  CHECK_EQ(5, m.Call(uint32_t(0xde3bcb20)));
+  CHECK_EQ(4, m.Call(uint32_t(0xd7e8a610)));
+  CHECK_EQ(3, m.Call(uint32_t(0x9afdbc88)));
+  CHECK_EQ(2, m.Call(uint32_t(0x9afdbc84)));
+  CHECK_EQ(1, m.Call(uint32_t(0x9afdbc82)));
+  CHECK_EQ(0, m.Call(uint32_t(0x9afdbc81)));
+}
+
+
+TEST(RunWord32Clz) {
+  BufferedRawMachineAssemblerTester<int32_t> m(MachineType::Uint32());
+  m.Return(m.Word32Clz(m.Parameter(0)));
+
+  CHECK_EQ(0, m.Call(uint32_t(0x80001000)));
+  CHECK_EQ(1, m.Call(uint32_t(0x40000500)));
+  CHECK_EQ(2, m.Call(uint32_t(0x20000300)));
+  CHECK_EQ(3, m.Call(uint32_t(0x10000003)));
+  CHECK_EQ(4, m.Call(uint32_t(0x08050000)));
+  CHECK_EQ(5, m.Call(uint32_t(0x04006000)));
+  CHECK_EQ(6, m.Call(uint32_t(0x02000000)));
+  CHECK_EQ(7, m.Call(uint32_t(0x010000a0)));
+  CHECK_EQ(8, m.Call(uint32_t(0x00800c00)));
+  CHECK_EQ(9, m.Call(uint32_t(0x00400000)));
+  CHECK_EQ(10, m.Call(uint32_t(0x0020000d)));
+  CHECK_EQ(11, m.Call(uint32_t(0x00100f00)));
+  CHECK_EQ(12, m.Call(uint32_t(0x00080000)));
+  CHECK_EQ(13, m.Call(uint32_t(0x00041000)));
+  CHECK_EQ(14, m.Call(uint32_t(0x00020020)));
+  CHECK_EQ(15, m.Call(uint32_t(0x00010300)));
+  CHECK_EQ(16, m.Call(uint32_t(0x00008040)));
+  CHECK_EQ(17, m.Call(uint32_t(0x00004005)));
+  CHECK_EQ(18, m.Call(uint32_t(0x00002050)));
+  CHECK_EQ(19, m.Call(uint32_t(0x00001700)));
+  CHECK_EQ(20, m.Call(uint32_t(0x00000870)));
+  CHECK_EQ(21, m.Call(uint32_t(0x00000405)));
+  CHECK_EQ(22, m.Call(uint32_t(0x00000203)));
+  CHECK_EQ(23, m.Call(uint32_t(0x00000101)));
+  CHECK_EQ(24, m.Call(uint32_t(0x00000089)));
+  CHECK_EQ(25, m.Call(uint32_t(0x00000041)));
+  CHECK_EQ(26, m.Call(uint32_t(0x00000022)));
+  CHECK_EQ(27, m.Call(uint32_t(0x00000013)));
+  CHECK_EQ(28, m.Call(uint32_t(0x00000008)));
+  CHECK_EQ(29, m.Call(uint32_t(0x00000004)));
+  CHECK_EQ(30, m.Call(uint32_t(0x00000002)));
+  CHECK_EQ(31, m.Call(uint32_t(0x00000001)));
+  CHECK_EQ(32, m.Call(uint32_t(0x00000000)));
+}
+
+
+TEST(RunWord32Popcnt) {
+  BufferedRawMachineAssemblerTester<int32_t> m(MachineType::Uint32());
+  if (!m.machine()->Word32Popcnt().IsSupported()) {
+    // We can only test the operator if it exists on the testing platform.
+    return;
+  }
+  m.Return(m.AddNode(m.machine()->Word32Popcnt().op(), m.Parameter(0)));
+
+  CHECK_EQ(0, m.Call(uint32_t(0x00000000)));
+  CHECK_EQ(1, m.Call(uint32_t(0x00000001)));
+  CHECK_EQ(1, m.Call(uint32_t(0x80000000)));
+  CHECK_EQ(32, m.Call(uint32_t(0xffffffff)));
+  CHECK_EQ(6, m.Call(uint32_t(0x000dc100)));
+  CHECK_EQ(9, m.Call(uint32_t(0xe00dc100)));
+  CHECK_EQ(11, m.Call(uint32_t(0xe00dc103)));
+  CHECK_EQ(9, m.Call(uint32_t(0x000dc107)));
+}
+
+
+#if V8_TARGET_ARCH_64_BIT
+TEST(RunWord64Clz) {
+  BufferedRawMachineAssemblerTester<int32_t> m(MachineType::Uint64());
+  m.Return(m.Word64Clz(m.Parameter(0)));
+
+  CHECK_EQ(0, m.Call(uint64_t(0x8000100000000000)));
+  CHECK_EQ(1, m.Call(uint64_t(0x4000050000000000)));
+  CHECK_EQ(2, m.Call(uint64_t(0x2000030000000000)));
+  CHECK_EQ(3, m.Call(uint64_t(0x1000000300000000)));
+  CHECK_EQ(4, m.Call(uint64_t(0x0805000000000000)));
+  CHECK_EQ(5, m.Call(uint64_t(0x0400600000000000)));
+  CHECK_EQ(6, m.Call(uint64_t(0x0200000000000000)));
+  CHECK_EQ(7, m.Call(uint64_t(0x010000a000000000)));
+  CHECK_EQ(8, m.Call(uint64_t(0x00800c0000000000)));
+  CHECK_EQ(9, m.Call(uint64_t(0x0040000000000000)));
+  CHECK_EQ(10, m.Call(uint64_t(0x0020000d00000000)));
+  CHECK_EQ(11, m.Call(uint64_t(0x00100f0000000000)));
+  CHECK_EQ(12, m.Call(uint64_t(0x0008000000000000)));
+  CHECK_EQ(13, m.Call(uint64_t(0x0004100000000000)));
+  CHECK_EQ(14, m.Call(uint64_t(0x0002002000000000)));
+  CHECK_EQ(15, m.Call(uint64_t(0x0001030000000000)));
+  CHECK_EQ(16, m.Call(uint64_t(0x0000804000000000)));
+  CHECK_EQ(17, m.Call(uint64_t(0x0000400500000000)));
+  CHECK_EQ(18, m.Call(uint64_t(0x0000205000000000)));
+  CHECK_EQ(19, m.Call(uint64_t(0x0000170000000000)));
+  CHECK_EQ(20, m.Call(uint64_t(0x0000087000000000)));
+  CHECK_EQ(21, m.Call(uint64_t(0x0000040500000000)));
+  CHECK_EQ(22, m.Call(uint64_t(0x0000020300000000)));
+  CHECK_EQ(23, m.Call(uint64_t(0x0000010100000000)));
+  CHECK_EQ(24, m.Call(uint64_t(0x0000008900000000)));
+  CHECK_EQ(25, m.Call(uint64_t(0x0000004100000000)));
+  CHECK_EQ(26, m.Call(uint64_t(0x0000002200000000)));
+  CHECK_EQ(27, m.Call(uint64_t(0x0000001300000000)));
+  CHECK_EQ(28, m.Call(uint64_t(0x0000000800000000)));
+  CHECK_EQ(29, m.Call(uint64_t(0x0000000400000000)));
+  CHECK_EQ(30, m.Call(uint64_t(0x0000000200000000)));
+  CHECK_EQ(31, m.Call(uint64_t(0x0000000100000000)));
+  CHECK_EQ(32, m.Call(uint64_t(0x0000000080001000)));
+  CHECK_EQ(33, m.Call(uint64_t(0x0000000040000500)));
+  CHECK_EQ(34, m.Call(uint64_t(0x0000000020000300)));
+  CHECK_EQ(35, m.Call(uint64_t(0x0000000010000003)));
+  CHECK_EQ(36, m.Call(uint64_t(0x0000000008050000)));
+  CHECK_EQ(37, m.Call(uint64_t(0x0000000004006000)));
+  CHECK_EQ(38, m.Call(uint64_t(0x0000000002000000)));
+  CHECK_EQ(39, m.Call(uint64_t(0x00000000010000a0)));
+  CHECK_EQ(40, m.Call(uint64_t(0x0000000000800c00)));
+  CHECK_EQ(41, m.Call(uint64_t(0x0000000000400000)));
+  CHECK_EQ(42, m.Call(uint64_t(0x000000000020000d)));
+  CHECK_EQ(43, m.Call(uint64_t(0x0000000000100f00)));
+  CHECK_EQ(44, m.Call(uint64_t(0x0000000000080000)));
+  CHECK_EQ(45, m.Call(uint64_t(0x0000000000041000)));
+  CHECK_EQ(46, m.Call(uint64_t(0x0000000000020020)));
+  CHECK_EQ(47, m.Call(uint64_t(0x0000000000010300)));
+  CHECK_EQ(48, m.Call(uint64_t(0x0000000000008040)));
+  CHECK_EQ(49, m.Call(uint64_t(0x0000000000004005)));
+  CHECK_EQ(50, m.Call(uint64_t(0x0000000000002050)));
+  CHECK_EQ(51, m.Call(uint64_t(0x0000000000001700)));
+  CHECK_EQ(52, m.Call(uint64_t(0x0000000000000870)));
+  CHECK_EQ(53, m.Call(uint64_t(0x0000000000000405)));
+  CHECK_EQ(54, m.Call(uint64_t(0x0000000000000203)));
+  CHECK_EQ(55, m.Call(uint64_t(0x0000000000000101)));
+  CHECK_EQ(56, m.Call(uint64_t(0x0000000000000089)));
+  CHECK_EQ(57, m.Call(uint64_t(0x0000000000000041)));
+  CHECK_EQ(58, m.Call(uint64_t(0x0000000000000022)));
+  CHECK_EQ(59, m.Call(uint64_t(0x0000000000000013)));
+  CHECK_EQ(60, m.Call(uint64_t(0x0000000000000008)));
+  CHECK_EQ(61, m.Call(uint64_t(0x0000000000000004)));
+  CHECK_EQ(62, m.Call(uint64_t(0x0000000000000002)));
+  CHECK_EQ(63, m.Call(uint64_t(0x0000000000000001)));
+  CHECK_EQ(64, m.Call(uint64_t(0x0000000000000000)));
+}
+
+
+TEST(RunWord64Ctz) {
+  RawMachineAssemblerTester<int32_t> m(MachineType::Uint64());
+  if (!m.machine()->Word64Ctz().IsSupported()) {
+    return;
+  }
+
+  m.Return(m.AddNode(m.machine()->Word64Ctz().op(), m.Parameter(0)));
+
+  CHECK_EQ(64, m.Call(uint64_t(0x0000000000000000)));
+  CHECK_EQ(63, m.Call(uint64_t(0x8000000000000000)));
+  CHECK_EQ(62, m.Call(uint64_t(0x4000000000000000)));
+  CHECK_EQ(61, m.Call(uint64_t(0x2000000000000000)));
+  CHECK_EQ(60, m.Call(uint64_t(0x1000000000000000)));
+  CHECK_EQ(59, m.Call(uint64_t(0xa800000000000000)));
+  CHECK_EQ(58, m.Call(uint64_t(0xf400000000000000)));
+  CHECK_EQ(57, m.Call(uint64_t(0x6200000000000000)));
+  CHECK_EQ(56, m.Call(uint64_t(0x9100000000000000)));
+  CHECK_EQ(55, m.Call(uint64_t(0xcd80000000000000)));
+  CHECK_EQ(54, m.Call(uint64_t(0x0940000000000000)));
+  CHECK_EQ(53, m.Call(uint64_t(0xaf20000000000000)));
+  CHECK_EQ(52, m.Call(uint64_t(0xac10000000000000)));
+  CHECK_EQ(51, m.Call(uint64_t(0xe0b8000000000000)));
+  CHECK_EQ(50, m.Call(uint64_t(0x9ce4000000000000)));
+  CHECK_EQ(49, m.Call(uint64_t(0xc792000000000000)));
+  CHECK_EQ(48, m.Call(uint64_t(0xb8f1000000000000)));
+  CHECK_EQ(47, m.Call(uint64_t(0x3b9f800000000000)));
+  CHECK_EQ(46, m.Call(uint64_t(0xdb4c400000000000)));
+  CHECK_EQ(45, m.Call(uint64_t(0xe9a3200000000000)));
+  CHECK_EQ(44, m.Call(uint64_t(0xfca6100000000000)));
+  CHECK_EQ(43, m.Call(uint64_t(0x6c8a780000000000)));
+  CHECK_EQ(42, m.Call(uint64_t(0x8ce5a40000000000)));
+  CHECK_EQ(41, m.Call(uint64_t(0xcb7d020000000000)));
+  CHECK_EQ(40, m.Call(uint64_t(0xcb4dc10000000000)));
+  CHECK_EQ(39, m.Call(uint64_t(0xdfbec58000000000)));
+  CHECK_EQ(38, m.Call(uint64_t(0x27a9db4000000000)));
+  CHECK_EQ(37, m.Call(uint64_t(0xde3bcb2000000000)));
+  CHECK_EQ(36, m.Call(uint64_t(0xd7e8a61000000000)));
+  CHECK_EQ(35, m.Call(uint64_t(0x9afdbc8800000000)));
+  CHECK_EQ(34, m.Call(uint64_t(0x9afdbc8400000000)));
+  CHECK_EQ(33, m.Call(uint64_t(0x9afdbc8200000000)));
+  CHECK_EQ(32, m.Call(uint64_t(0x9afdbc8100000000)));
+  CHECK_EQ(31, m.Call(uint64_t(0x0000000080000000)));
+  CHECK_EQ(30, m.Call(uint64_t(0x0000000040000000)));
+  CHECK_EQ(29, m.Call(uint64_t(0x0000000020000000)));
+  CHECK_EQ(28, m.Call(uint64_t(0x0000000010000000)));
+  CHECK_EQ(27, m.Call(uint64_t(0x00000000a8000000)));
+  CHECK_EQ(26, m.Call(uint64_t(0x00000000f4000000)));
+  CHECK_EQ(25, m.Call(uint64_t(0x0000000062000000)));
+  CHECK_EQ(24, m.Call(uint64_t(0x0000000091000000)));
+  CHECK_EQ(23, m.Call(uint64_t(0x00000000cd800000)));
+  CHECK_EQ(22, m.Call(uint64_t(0x0000000009400000)));
+  CHECK_EQ(21, m.Call(uint64_t(0x00000000af200000)));
+  CHECK_EQ(20, m.Call(uint64_t(0x00000000ac100000)));
+  CHECK_EQ(19, m.Call(uint64_t(0x00000000e0b80000)));
+  CHECK_EQ(18, m.Call(uint64_t(0x000000009ce40000)));
+  CHECK_EQ(17, m.Call(uint64_t(0x00000000c7920000)));
+  CHECK_EQ(16, m.Call(uint64_t(0x00000000b8f10000)));
+  CHECK_EQ(15, m.Call(uint64_t(0x000000003b9f8000)));
+  CHECK_EQ(14, m.Call(uint64_t(0x00000000db4c4000)));
+  CHECK_EQ(13, m.Call(uint64_t(0x00000000e9a32000)));
+  CHECK_EQ(12, m.Call(uint64_t(0x00000000fca61000)));
+  CHECK_EQ(11, m.Call(uint64_t(0x000000006c8a7800)));
+  CHECK_EQ(10, m.Call(uint64_t(0x000000008ce5a400)));
+  CHECK_EQ(9, m.Call(uint64_t(0x00000000cb7d0200)));
+  CHECK_EQ(8, m.Call(uint64_t(0x00000000cb4dc100)));
+  CHECK_EQ(7, m.Call(uint64_t(0x00000000dfbec580)));
+  CHECK_EQ(6, m.Call(uint64_t(0x0000000027a9db40)));
+  CHECK_EQ(5, m.Call(uint64_t(0x00000000de3bcb20)));
+  CHECK_EQ(4, m.Call(uint64_t(0x00000000d7e8a610)));
+  CHECK_EQ(3, m.Call(uint64_t(0x000000009afdbc88)));
+  CHECK_EQ(2, m.Call(uint64_t(0x000000009afdbc84)));
+  CHECK_EQ(1, m.Call(uint64_t(0x000000009afdbc82)));
+  CHECK_EQ(0, m.Call(uint64_t(0x000000009afdbc81)));
+}
+
+
+TEST(RunWord64Popcnt) {
+  BufferedRawMachineAssemblerTester<int32_t> m(MachineType::Uint64());
+  if (!m.machine()->Word64Popcnt().IsSupported()) {
+    return;
+  }
+
+  m.Return(m.AddNode(m.machine()->Word64Popcnt().op(), m.Parameter(0)));
+
+  CHECK_EQ(0, m.Call(uint64_t(0x0000000000000000)));
+  CHECK_EQ(1, m.Call(uint64_t(0x0000000000000001)));
+  CHECK_EQ(1, m.Call(uint64_t(0x8000000000000000)));
+  CHECK_EQ(64, m.Call(uint64_t(0xffffffffffffffff)));
+  CHECK_EQ(12, m.Call(uint64_t(0x000dc100000dc100)));
+  CHECK_EQ(18, m.Call(uint64_t(0xe00dc100e00dc100)));
+  CHECK_EQ(22, m.Call(uint64_t(0xe00dc103e00dc103)));
+  CHECK_EQ(18, m.Call(uint64_t(0x000dc107000dc107)));
+}
+#endif  // V8_TARGET_ARCH_64_BIT
+
+
 static Node* Int32Input(RawMachineAssemblerTester<int32_t>* m, int index) {
   switch (index) {
     case 0:
@@ -49,7 +318,7 @@
     case 6:
       return m->Int32Constant(0x01234567);
     case 7:
-      return m->Load(kMachInt32, m->PointerConstant(NULL));
+      return m->Load(MachineType::Int32(), m->PointerConstant(NULL));
     default:
       return NULL;
   }
@@ -74,10 +343,11 @@
   for (size_t i = 0; i < arraysize(kOps); ++i) {
     for (int j = 0; j < 8; j++) {
       for (int k = 0; k < 8; k++) {
-        RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32);
+        RawMachineAssemblerTester<int32_t> m(MachineType::Int32(),
+                                             MachineType::Int32());
         Node* a = Int32Input(&m, j);
         Node* b = Int32Input(&m, k);
-        m.Return(m.NewNode(kOps[i], a, b));
+        m.Return(m.AddNode(kOps[i], a, b));
         m.GenerateCode();
       }
     }
@@ -85,11 +355,260 @@
 }
 
 
+TEST(CodeGenNop) {
+  RawMachineAssemblerTester<void> m;
+  m.Return(m.Int32Constant(0));
+  m.GenerateCode();
+}
+
+
+#if V8_TARGET_ARCH_64_BIT
+static Node* Int64Input(RawMachineAssemblerTester<int64_t>* m, int index) {
+  switch (index) {
+    case 0:
+      return m->Parameter(0);
+    case 1:
+      return m->Parameter(1);
+    case 2:
+      return m->Int64Constant(0);
+    case 3:
+      return m->Int64Constant(1);
+    case 4:
+      return m->Int64Constant(-1);
+    case 5:
+      return m->Int64Constant(0xff);
+    case 6:
+      return m->Int64Constant(0x0123456789abcdefLL);
+    case 7:
+      return m->Load(MachineType::Int64(), m->PointerConstant(NULL));
+    default:
+      return NULL;
+  }
+}
+
+
+TEST(CodeGenInt64Binop) {
+  RawMachineAssemblerTester<void> m;
+
+  const Operator* kOps[] = {
+      m.machine()->Word64And(), m.machine()->Word64Or(),
+      m.machine()->Word64Xor(), m.machine()->Word64Shl(),
+      m.machine()->Word64Shr(), m.machine()->Word64Sar(),
+      m.machine()->Word64Equal(), m.machine()->Int64Add(),
+      m.machine()->Int64Sub(), m.machine()->Int64Mul(), m.machine()->Int64Div(),
+      m.machine()->Uint64Div(), m.machine()->Int64Mod(),
+      m.machine()->Uint64Mod(), m.machine()->Int64LessThan(),
+      m.machine()->Int64LessThanOrEqual(), m.machine()->Uint64LessThan(),
+      m.machine()->Uint64LessThanOrEqual()};
+
+  for (size_t i = 0; i < arraysize(kOps); ++i) {
+    for (int j = 0; j < 8; j++) {
+      for (int k = 0; k < 8; k++) {
+        RawMachineAssemblerTester<int64_t> m(MachineType::Int64(),
+                                             MachineType::Int64());
+        Node* a = Int64Input(&m, j);
+        Node* b = Int64Input(&m, k);
+        m.Return(m.AddNode(kOps[i], a, b));
+        m.GenerateCode();
+      }
+    }
+  }
+}
+
+
+TEST(RunInt64AddWithOverflowP) {
+  int64_t actual_val = -1;
+  RawMachineAssemblerTester<int32_t> m;
+  Int64BinopTester bt(&m);
+  Node* add = m.Int64AddWithOverflow(bt.param0, bt.param1);
+  Node* val = m.Projection(0, add);
+  Node* ovf = m.Projection(1, add);
+  m.StoreToPointer(&actual_val, MachineRepresentation::kWord64, val);
+  bt.AddReturn(ovf);
+  FOR_INT64_INPUTS(i) {
+    FOR_INT64_INPUTS(j) {
+      int64_t expected_val;
+      int expected_ovf = bits::SignedAddOverflow64(*i, *j, &expected_val);
+      CHECK_EQ(expected_ovf, bt.call(*i, *j));
+      CHECK_EQ(expected_val, actual_val);
+    }
+  }
+}
+
+
+TEST(RunInt64AddWithOverflowImm) {
+  int64_t actual_val = -1, expected_val = 0;
+  FOR_INT64_INPUTS(i) {
+    {
+      RawMachineAssemblerTester<int32_t> m(MachineType::Int64());
+      Node* add = m.Int64AddWithOverflow(m.Int64Constant(*i), m.Parameter(0));
+      Node* val = m.Projection(0, add);
+      Node* ovf = m.Projection(1, add);
+      m.StoreToPointer(&actual_val, MachineRepresentation::kWord64, val);
+      m.Return(ovf);
+      FOR_INT64_INPUTS(j) {
+        int expected_ovf = bits::SignedAddOverflow64(*i, *j, &expected_val);
+        CHECK_EQ(expected_ovf, m.Call(*j));
+        CHECK_EQ(expected_val, actual_val);
+      }
+    }
+    {
+      RawMachineAssemblerTester<int32_t> m(MachineType::Int64());
+      Node* add = m.Int64AddWithOverflow(m.Parameter(0), m.Int64Constant(*i));
+      Node* val = m.Projection(0, add);
+      Node* ovf = m.Projection(1, add);
+      m.StoreToPointer(&actual_val, MachineRepresentation::kWord64, val);
+      m.Return(ovf);
+      FOR_INT64_INPUTS(j) {
+        int expected_ovf = bits::SignedAddOverflow64(*i, *j, &expected_val);
+        CHECK_EQ(expected_ovf, m.Call(*j));
+        CHECK_EQ(expected_val, actual_val);
+      }
+    }
+    FOR_INT64_INPUTS(j) {
+      RawMachineAssemblerTester<int32_t> m;
+      Node* add =
+          m.Int64AddWithOverflow(m.Int64Constant(*i), m.Int64Constant(*j));
+      Node* val = m.Projection(0, add);
+      Node* ovf = m.Projection(1, add);
+      m.StoreToPointer(&actual_val, MachineRepresentation::kWord64, val);
+      m.Return(ovf);
+      int expected_ovf = bits::SignedAddOverflow64(*i, *j, &expected_val);
+      CHECK_EQ(expected_ovf, m.Call());
+      CHECK_EQ(expected_val, actual_val);
+    }
+  }
+}
+
+
+TEST(RunInt64AddWithOverflowInBranchP) {
+  int constant = 911777;
+  RawMachineLabel blocka, blockb;
+  RawMachineAssemblerTester<int32_t> m;
+  Int64BinopTester bt(&m);
+  Node* add = m.Int64AddWithOverflow(bt.param0, bt.param1);
+  Node* ovf = m.Projection(1, add);
+  m.Branch(ovf, &blocka, &blockb);
+  m.Bind(&blocka);
+  bt.AddReturn(m.Int64Constant(constant));
+  m.Bind(&blockb);
+  Node* val = m.Projection(0, add);
+  Node* truncated = m.TruncateInt64ToInt32(val);
+  bt.AddReturn(truncated);
+  FOR_INT64_INPUTS(i) {
+    FOR_INT64_INPUTS(j) {
+      int32_t expected = constant;
+      int64_t result;
+      if (!bits::SignedAddOverflow64(*i, *j, &result)) {
+        expected = static_cast<int32_t>(result);
+      }
+      CHECK_EQ(expected, bt.call(*i, *j));
+    }
+  }
+}
+
+
+TEST(RunInt64SubWithOverflowP) {
+  int64_t actual_val = -1;
+  RawMachineAssemblerTester<int32_t> m;
+  Int64BinopTester bt(&m);
+  Node* add = m.Int64SubWithOverflow(bt.param0, bt.param1);
+  Node* val = m.Projection(0, add);
+  Node* ovf = m.Projection(1, add);
+  m.StoreToPointer(&actual_val, MachineRepresentation::kWord64, val);
+  bt.AddReturn(ovf);
+  FOR_INT64_INPUTS(i) {
+    FOR_INT64_INPUTS(j) {
+      int64_t expected_val;
+      int expected_ovf = bits::SignedSubOverflow64(*i, *j, &expected_val);
+      CHECK_EQ(expected_ovf, bt.call(*i, *j));
+      CHECK_EQ(expected_val, actual_val);
+    }
+  }
+}
+
+
+TEST(RunInt64SubWithOverflowImm) {
+  int64_t actual_val = -1, expected_val = 0;
+  FOR_INT64_INPUTS(i) {
+    {
+      RawMachineAssemblerTester<int32_t> m(MachineType::Int64());
+      Node* add = m.Int64SubWithOverflow(m.Int64Constant(*i), m.Parameter(0));
+      Node* val = m.Projection(0, add);
+      Node* ovf = m.Projection(1, add);
+      m.StoreToPointer(&actual_val, MachineRepresentation::kWord64, val);
+      m.Return(ovf);
+      FOR_INT64_INPUTS(j) {
+        int expected_ovf = bits::SignedSubOverflow64(*i, *j, &expected_val);
+        CHECK_EQ(expected_ovf, m.Call(*j));
+        CHECK_EQ(expected_val, actual_val);
+      }
+    }
+    {
+      RawMachineAssemblerTester<int32_t> m(MachineType::Int64());
+      Node* add = m.Int64SubWithOverflow(m.Parameter(0), m.Int64Constant(*i));
+      Node* val = m.Projection(0, add);
+      Node* ovf = m.Projection(1, add);
+      m.StoreToPointer(&actual_val, MachineRepresentation::kWord64, val);
+      m.Return(ovf);
+      FOR_INT64_INPUTS(j) {
+        int expected_ovf = bits::SignedSubOverflow64(*j, *i, &expected_val);
+        CHECK_EQ(expected_ovf, m.Call(*j));
+        CHECK_EQ(expected_val, actual_val);
+      }
+    }
+    FOR_INT64_INPUTS(j) {
+      RawMachineAssemblerTester<int32_t> m;
+      Node* add =
+          m.Int64SubWithOverflow(m.Int64Constant(*i), m.Int64Constant(*j));
+      Node* val = m.Projection(0, add);
+      Node* ovf = m.Projection(1, add);
+      m.StoreToPointer(&actual_val, MachineRepresentation::kWord64, val);
+      m.Return(ovf);
+      int expected_ovf = bits::SignedSubOverflow64(*i, *j, &expected_val);
+      CHECK_EQ(expected_ovf, m.Call());
+      CHECK_EQ(expected_val, actual_val);
+    }
+  }
+}
+
+
+TEST(RunInt64SubWithOverflowInBranchP) {
+  int constant = 911999;
+  RawMachineLabel blocka, blockb;
+  RawMachineAssemblerTester<int32_t> m;
+  Int64BinopTester bt(&m);
+  Node* sub = m.Int64SubWithOverflow(bt.param0, bt.param1);
+  Node* ovf = m.Projection(1, sub);
+  m.Branch(ovf, &blocka, &blockb);
+  m.Bind(&blocka);
+  bt.AddReturn(m.Int64Constant(constant));
+  m.Bind(&blockb);
+  Node* val = m.Projection(0, sub);
+  Node* truncated = m.TruncateInt64ToInt32(val);
+  bt.AddReturn(truncated);
+  FOR_INT64_INPUTS(i) {
+    FOR_INT64_INPUTS(j) {
+      int32_t expected = constant;
+      int64_t result;
+      if (!bits::SignedSubOverflow64(*i, *j, &result)) {
+        expected = static_cast<int32_t>(result);
+      }
+      CHECK_EQ(expected, static_cast<int32_t>(bt.call(*i, *j)));
+    }
+  }
+}
+
+
+// TODO(titzer): add tests that run 64-bit integer operations.
+#endif  // V8_TARGET_ARCH_64_BIT
+
+
 TEST(RunGoto) {
   RawMachineAssemblerTester<int32_t> m;
   int constant = 99999;
 
-  MLabel next;
+  RawMachineLabel next;
   m.Goto(&next);
   m.Bind(&next);
   m.Return(m.Int32Constant(constant));
@@ -102,7 +621,7 @@
   RawMachineAssemblerTester<int32_t> m;
   int constant = 9999977;
 
-  MLabel labels[10];
+  RawMachineLabel labels[10];
   for (size_t i = 0; i < arraysize(labels); i++) {
     m.Goto(&labels[i]);
     m.Bind(&labels[i]);
@@ -117,7 +636,7 @@
   RawMachineAssemblerTester<int32_t> m;
   int constant = 999777;
 
-  MLabel blocka, blockb;
+  RawMachineLabel blocka, blockb;
   m.Branch(m.Int32Constant(0), &blocka, &blockb);
   m.Bind(&blocka);
   m.Return(m.Int32Constant(0 - constant));
@@ -133,7 +652,7 @@
 
   int constant = 995666;
 
-  MLabel blocka, blockb, end;
+  RawMachineLabel blocka, blockb, end;
   m.Branch(m.Int32Constant(0), &blocka, &blockb);
   m.Bind(&blocka);
   m.Goto(&end);
@@ -150,7 +669,7 @@
   RawMachineAssemblerTester<int32_t> m;
   int constant = 999555;
 
-  MLabel header, body, exit;
+  RawMachineLabel header, body, exit;
   m.Goto(&header);
   m.Bind(&header);
   m.Branch(m.Int32Constant(0), &body, &exit);
@@ -165,62 +684,65 @@
 
 template <typename R>
 static void BuildDiamondPhi(RawMachineAssemblerTester<R>* m, Node* cond_node,
-                            MachineType type, Node* true_node,
+                            MachineRepresentation rep, Node* true_node,
                             Node* false_node) {
-  MLabel blocka, blockb;
-  MLabel* end = m->Exit();
+  RawMachineLabel blocka, blockb, end;
   m->Branch(cond_node, &blocka, &blockb);
   m->Bind(&blocka);
-  m->Goto(end);
+  m->Goto(&end);
   m->Bind(&blockb);
-  m->Goto(end);
+  m->Goto(&end);
 
-  m->Bind(end);
-  Node* phi = m->Phi(type, true_node, false_node);
+  m->Bind(&end);
+  Node* phi = m->Phi(rep, true_node, false_node);
   m->Return(phi);
 }
 
 
 TEST(RunDiamondPhiConst) {
-  RawMachineAssemblerTester<int32_t> m(kMachInt32);
+  RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
   int false_val = 0xFF666;
   int true_val = 0x00DDD;
   Node* true_node = m.Int32Constant(true_val);
   Node* false_node = m.Int32Constant(false_val);
-  BuildDiamondPhi(&m, m.Parameter(0), kMachInt32, true_node, false_node);
+  BuildDiamondPhi(&m, m.Parameter(0), MachineRepresentation::kWord32, true_node,
+                  false_node);
   CHECK_EQ(false_val, m.Call(0));
   CHECK_EQ(true_val, m.Call(1));
 }
 
 
 TEST(RunDiamondPhiNumber) {
-  RawMachineAssemblerTester<Object*> m(kMachInt32);
+  RawMachineAssemblerTester<Object*> m(MachineType::Int32());
   double false_val = -11.1;
   double true_val = 200.1;
   Node* true_node = m.NumberConstant(true_val);
   Node* false_node = m.NumberConstant(false_val);
-  BuildDiamondPhi(&m, m.Parameter(0), kMachAnyTagged, true_node, false_node);
+  BuildDiamondPhi(&m, m.Parameter(0), MachineRepresentation::kTagged, true_node,
+                  false_node);
   m.CheckNumber(false_val, m.Call(0));
   m.CheckNumber(true_val, m.Call(1));
 }
 
 
 TEST(RunDiamondPhiString) {
-  RawMachineAssemblerTester<Object*> m(kMachInt32);
+  RawMachineAssemblerTester<Object*> m(MachineType::Int32());
   const char* false_val = "false";
   const char* true_val = "true";
   Node* true_node = m.StringConstant(true_val);
   Node* false_node = m.StringConstant(false_val);
-  BuildDiamondPhi(&m, m.Parameter(0), kMachAnyTagged, true_node, false_node);
+  BuildDiamondPhi(&m, m.Parameter(0), MachineRepresentation::kTagged, true_node,
+                  false_node);
   m.CheckString(false_val, m.Call(0));
   m.CheckString(true_val, m.Call(1));
 }
 
 
 TEST(RunDiamondPhiParam) {
-  RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32, kMachInt32);
-  BuildDiamondPhi(&m, m.Parameter(0), kMachInt32, m.Parameter(1),
-                  m.Parameter(2));
+  RawMachineAssemblerTester<int32_t> m(
+      MachineType::Int32(), MachineType::Int32(), MachineType::Int32());
+  BuildDiamondPhi(&m, m.Parameter(0), MachineRepresentation::kWord32,
+                  m.Parameter(1), m.Parameter(2));
   int32_t c1 = 0x260cb75a;
   int32_t c2 = 0xcd3e9c8b;
   int result = m.Call(0, c1, c2);
@@ -240,16 +762,15 @@
   Node* false_node = m.Int32Constant(false_val);
 
   // x = false_val; while(false) { x = true_val; } return x;
-  MLabel body, header;
-  MLabel* end = m.Exit();
+  RawMachineLabel body, header, end;
 
   m.Goto(&header);
   m.Bind(&header);
-  Node* phi = m.Phi(kMachInt32, false_node, true_node);
-  m.Branch(cond_node, &body, end);
+  Node* phi = m.Phi(MachineRepresentation::kWord32, false_node, true_node);
+  m.Branch(cond_node, &body, &end);
   m.Bind(&body);
   m.Goto(&header);
-  m.Bind(end);
+  m.Bind(&end);
   m.Return(phi);
 
   CHECK_EQ(false_val, m.Call());
@@ -257,22 +778,24 @@
 
 
 TEST(RunLoopPhiParam) {
-  RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32, kMachInt32);
+  RawMachineAssemblerTester<int32_t> m(
+      MachineType::Int32(), MachineType::Int32(), MachineType::Int32());
 
-  MLabel blocka, blockb;
-  MLabel* end = m.Exit();
+  RawMachineLabel blocka, blockb, end;
 
   m.Goto(&blocka);
 
   m.Bind(&blocka);
-  Node* phi = m.Phi(kMachInt32, m.Parameter(1), m.Parameter(2));
-  Node* cond = m.Phi(kMachInt32, m.Parameter(0), m.Int32Constant(0));
-  m.Branch(cond, &blockb, end);
+  Node* phi =
+      m.Phi(MachineRepresentation::kWord32, m.Parameter(1), m.Parameter(2));
+  Node* cond =
+      m.Phi(MachineRepresentation::kWord32, m.Parameter(0), m.Int32Constant(0));
+  m.Branch(cond, &blockb, &end);
 
   m.Bind(&blockb);
   m.Goto(&blocka);
 
-  m.Bind(end);
+  m.Bind(&end);
   m.Return(phi);
 
   int32_t c1 = 0xa81903b4;
@@ -290,22 +813,21 @@
   int false_val = 0x10777;
 
   // x = false_val; while(false) { x++; } return x;
-  MLabel header, body;
-  MLabel* end = m.Exit();
+  RawMachineLabel header, body, end;
   Node* false_node = m.Int32Constant(false_val);
 
   m.Goto(&header);
 
   m.Bind(&header);
-  Node* phi = m.Phi(kMachInt32, false_node, false_node);
-  m.Branch(m.Int32Constant(0), &body, end);
+  Node* phi = m.Phi(MachineRepresentation::kWord32, false_node, false_node);
+  m.Branch(m.Int32Constant(0), &body, &end);
 
   m.Bind(&body);
   Node* add = m.Int32Add(phi, m.Int32Constant(1));
   phi->ReplaceInput(1, add);
   m.Goto(&header);
 
-  m.Bind(end);
+  m.Bind(&end);
   m.Return(phi);
 
   CHECK_EQ(false_val, m.Call());
@@ -317,21 +839,20 @@
   Int32BinopTester bt(&m);
 
   // x = 0; while(x ^ param) { x++; } return x;
-  MLabel header, body;
-  MLabel* end = m.Exit();
+  RawMachineLabel header, body, end;
   Node* zero = m.Int32Constant(0);
 
   m.Goto(&header);
 
   m.Bind(&header);
-  Node* phi = m.Phi(kMachInt32, zero, zero);
-  m.Branch(m.WordXor(phi, bt.param0), &body, end);
+  Node* phi = m.Phi(MachineRepresentation::kWord32, zero, zero);
+  m.Branch(m.WordXor(phi, bt.param0), &body, &end);
 
   m.Bind(&body);
   phi->ReplaceInput(1, m.Int32Add(phi, m.Int32Constant(1)));
   m.Goto(&header);
 
-  m.Bind(end);
+  m.Bind(&end);
   bt.AddReturn(phi);
 
   CHECK_EQ(11, bt.call(11, 0));
@@ -345,21 +866,20 @@
   Int32BinopTester bt(&m);
 
   // x = 0; while(x < param) { x++; } return x;
-  MLabel header, body;
-  MLabel* end = m.Exit();
+  RawMachineLabel header, body, end;
   Node* zero = m.Int32Constant(0);
 
   m.Goto(&header);
 
   m.Bind(&header);
-  Node* phi = m.Phi(kMachInt32, zero, zero);
-  m.Branch(m.Int32LessThan(phi, bt.param0), &body, end);
+  Node* phi = m.Phi(MachineRepresentation::kWord32, zero, zero);
+  m.Branch(m.Int32LessThan(phi, bt.param0), &body, &end);
 
   m.Bind(&body);
   phi->ReplaceInput(1, m.Int32Add(phi, m.Int32Constant(1)));
   m.Goto(&header);
 
-  m.Bind(end);
+  m.Bind(&end);
   bt.AddReturn(phi);
 
   CHECK_EQ(11, bt.call(11, 0));
@@ -374,21 +894,20 @@
   Int32BinopTester bt(&m);
 
   // x = 0; while(x < param) { x++; } return x;
-  MLabel header, body;
-  MLabel* end = m.Exit();
+  RawMachineLabel header, body, end;
   Node* zero = m.Int32Constant(0);
 
   m.Goto(&header);
 
   m.Bind(&header);
-  Node* phi = m.Phi(kMachInt32, zero, zero);
-  m.Branch(m.Uint32LessThan(phi, bt.param0), &body, end);
+  Node* phi = m.Phi(MachineRepresentation::kWord32, zero, zero);
+  m.Branch(m.Uint32LessThan(phi, bt.param0), &body, &end);
 
   m.Bind(&body);
   phi->ReplaceInput(1, m.Int32Add(phi, m.Int32Constant(1)));
   m.Goto(&header);
 
-  m.Bind(end);
+  m.Bind(&end);
   bt.AddReturn(phi);
 
   CHECK_EQ(11, bt.call(11, 0));
@@ -403,20 +922,20 @@
   Int32BinopTester bt(&m);
 
   // x = param; while(x) { x--; } return x;
-  MLabel header, body;
-  MLabel* end = m.Exit();
+  RawMachineLabel header, body, end;
 
   m.Goto(&header);
 
   m.Bind(&header);
-  Node* phi = m.Phi(kMachInt32, bt.param0, m.Int32Constant(0));
-  m.Branch(phi, &body, end);
+  Node* phi =
+      m.Phi(MachineRepresentation::kWord32, bt.param0, m.Int32Constant(0));
+  m.Branch(phi, &body, &end);
 
   m.Bind(&body);
   phi->ReplaceInput(1, m.Int32Sub(phi, m.Int32Constant(1)));
   m.Goto(&header);
 
-  m.Bind(end);
+  m.Bind(&end);
   bt.AddReturn(phi);
 
   CHECK_EQ(0, bt.call(11, 0));
@@ -425,37 +944,172 @@
 }
 
 
+TEST(RunLoopIncrementFloat32) {
+  RawMachineAssemblerTester<int32_t> m;
+
+  // x = -3.0f; while(x < 10f) { x = x + 0.5f; } return (int) (double) x;
+  RawMachineLabel header, body, end;
+  Node* minus_3 = m.Float32Constant(-3.0f);
+  Node* ten = m.Float32Constant(10.0f);
+
+  m.Goto(&header);
+
+  m.Bind(&header);
+  Node* phi = m.Phi(MachineRepresentation::kFloat32, minus_3, ten);
+  m.Branch(m.Float32LessThan(phi, ten), &body, &end);
+
+  m.Bind(&body);
+  phi->ReplaceInput(1, m.Float32Add(phi, m.Float32Constant(0.5f)));
+  m.Goto(&header);
+
+  m.Bind(&end);
+  m.Return(m.ChangeFloat64ToInt32(m.ChangeFloat32ToFloat64(phi)));
+
+  CHECK_EQ(10, m.Call());
+}
+
+
 TEST(RunLoopIncrementFloat64) {
   RawMachineAssemblerTester<int32_t> m;
 
   // x = -3.0; while(x < 10) { x = x + 0.5; } return (int) x;
-  MLabel header, body;
-  MLabel* end = m.Exit();
+  RawMachineLabel header, body, end;
   Node* minus_3 = m.Float64Constant(-3.0);
   Node* ten = m.Float64Constant(10.0);
 
   m.Goto(&header);
 
   m.Bind(&header);
-  Node* phi = m.Phi(kMachFloat64, minus_3, ten);
-  m.Branch(m.Float64LessThan(phi, ten), &body, end);
+  Node* phi = m.Phi(MachineRepresentation::kFloat64, minus_3, ten);
+  m.Branch(m.Float64LessThan(phi, ten), &body, &end);
 
   m.Bind(&body);
   phi->ReplaceInput(1, m.Float64Add(phi, m.Float64Constant(0.5)));
   m.Goto(&header);
 
-  m.Bind(end);
+  m.Bind(&end);
   m.Return(m.ChangeFloat64ToInt32(phi));
 
   CHECK_EQ(10, m.Call());
 }
 
 
+TEST(RunSwitch1) {
+  RawMachineAssemblerTester<int32_t> m;
+
+  int constant = 11223344;
+
+  RawMachineLabel block0, block1, def, end;
+  RawMachineLabel* case_labels[] = {&block0, &block1};
+  int32_t case_values[] = {0, 1};
+  m.Switch(m.Int32Constant(0), &def, case_values, case_labels,
+           arraysize(case_labels));
+  m.Bind(&block0);
+  m.Goto(&end);
+  m.Bind(&block1);
+  m.Goto(&end);
+  m.Bind(&def);
+  m.Goto(&end);
+  m.Bind(&end);
+  m.Return(m.Int32Constant(constant));
+
+  CHECK_EQ(constant, m.Call());
+}
+
+
+TEST(RunSwitch2) {
+  RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
+
+  RawMachineLabel blocka, blockb, blockc;
+  RawMachineLabel* case_labels[] = {&blocka, &blockb};
+  int32_t case_values[] = {std::numeric_limits<int32_t>::min(),
+                           std::numeric_limits<int32_t>::max()};
+  m.Switch(m.Parameter(0), &blockc, case_values, case_labels,
+           arraysize(case_labels));
+  m.Bind(&blocka);
+  m.Return(m.Int32Constant(-1));
+  m.Bind(&blockb);
+  m.Return(m.Int32Constant(1));
+  m.Bind(&blockc);
+  m.Return(m.Int32Constant(0));
+
+  CHECK_EQ(1, m.Call(std::numeric_limits<int32_t>::max()));
+  CHECK_EQ(-1, m.Call(std::numeric_limits<int32_t>::min()));
+  for (int i = -100; i < 100; i += 25) {
+    CHECK_EQ(0, m.Call(i));
+  }
+}
+
+
+TEST(RunSwitch3) {
+  RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
+
+  RawMachineLabel blocka, blockb, blockc;
+  RawMachineLabel* case_labels[] = {&blocka, &blockb};
+  int32_t case_values[] = {std::numeric_limits<int32_t>::min() + 0,
+                           std::numeric_limits<int32_t>::min() + 1};
+  m.Switch(m.Parameter(0), &blockc, case_values, case_labels,
+           arraysize(case_labels));
+  m.Bind(&blocka);
+  m.Return(m.Int32Constant(0));
+  m.Bind(&blockb);
+  m.Return(m.Int32Constant(1));
+  m.Bind(&blockc);
+  m.Return(m.Int32Constant(2));
+
+  CHECK_EQ(0, m.Call(std::numeric_limits<int32_t>::min() + 0));
+  CHECK_EQ(1, m.Call(std::numeric_limits<int32_t>::min() + 1));
+  for (int i = -100; i < 100; i += 25) {
+    CHECK_EQ(2, m.Call(i));
+  }
+}
+
+
+TEST(RunSwitch4) {
+  RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
+
+  const size_t kNumCases = 512;
+  const size_t kNumValues = kNumCases + 1;
+  int32_t values[kNumValues];
+  m.main_isolate()->random_number_generator()->NextBytes(values,
+                                                         sizeof(values));
+  RawMachineLabel end, def;
+  int32_t case_values[kNumCases];
+  RawMachineLabel* case_labels[kNumCases];
+  Node* results[kNumValues];
+  for (size_t i = 0; i < kNumCases; ++i) {
+    case_values[i] = static_cast<int32_t>(i);
+    case_labels[i] =
+        new (m.main_zone()->New(sizeof(RawMachineLabel))) RawMachineLabel;
+  }
+  m.Switch(m.Parameter(0), &def, case_values, case_labels,
+           arraysize(case_labels));
+  for (size_t i = 0; i < kNumCases; ++i) {
+    m.Bind(case_labels[i]);
+    results[i] = m.Int32Constant(values[i]);
+    m.Goto(&end);
+  }
+  m.Bind(&def);
+  results[kNumCases] = m.Int32Constant(values[kNumCases]);
+  m.Goto(&end);
+  m.Bind(&end);
+  const int num_results = static_cast<int>(arraysize(results));
+  Node* phi =
+      m.AddNode(m.common()->Phi(MachineRepresentation::kWord32, num_results),
+                num_results, results);
+  m.Return(phi);
+
+  for (size_t i = 0; i < kNumValues; ++i) {
+    CHECK_EQ(values[i], m.Call(static_cast<int>(i)));
+  }
+}
+
+
 TEST(RunLoadInt32) {
   RawMachineAssemblerTester<int32_t> m;
 
   int32_t p1 = 0;  // loads directly from this location.
-  m.Return(m.LoadFromPointer(&p1, kMachInt32));
+  m.Return(m.LoadFromPointer(&p1, MachineType::Int32()));
 
   FOR_INT32_INPUTS(i) {
     p1 = *i;
@@ -475,7 +1129,7 @@
     int32_t offset = offsets[i];
     byte* pointer = reinterpret_cast<byte*>(&p1) - offset;
     // generate load [#base + #index]
-    m.Return(m.LoadFromPointer(pointer, kMachInt32, offset));
+    m.Return(m.LoadFromPointer(pointer, MachineType::Int32(), offset));
 
     FOR_INT32_INPUTS(j) {
       p1 = *j;
@@ -485,6 +1139,33 @@
 }
 
 
+TEST(RunLoadStoreFloat32Offset) {
+  float p1 = 0.0f;  // loads directly from this location.
+  float p2 = 0.0f;  // and stores directly into this location.
+
+  FOR_INT32_INPUTS(i) {
+    int32_t magic = 0x2342aabb + *i * 3;
+    RawMachineAssemblerTester<int32_t> m;
+    int32_t offset = *i;
+    byte* from = reinterpret_cast<byte*>(&p1) - offset;
+    byte* to = reinterpret_cast<byte*>(&p2) - offset;
+    // generate load [#base + #index]
+    Node* load = m.Load(MachineType::Float32(), m.PointerConstant(from),
+                        m.IntPtrConstant(offset));
+    m.Store(MachineRepresentation::kFloat32, m.PointerConstant(to),
+            m.IntPtrConstant(offset), load, kNoWriteBarrier);
+    m.Return(m.Int32Constant(magic));
+
+    FOR_FLOAT32_INPUTS(j) {
+      p1 = *j;
+      p2 = *j - 5;
+      CHECK_EQ(magic, m.Call());
+      CheckDoubleEq(p1, p2);
+    }
+  }
+}
+
+
 TEST(RunLoadStoreFloat64Offset) {
   double p1 = 0;  // loads directly from this location.
   double p2 = 0;  // and stores directly into this location.
@@ -496,16 +1177,17 @@
     byte* from = reinterpret_cast<byte*>(&p1) - offset;
     byte* to = reinterpret_cast<byte*>(&p2) - offset;
     // generate load [#base + #index]
-    Node* load =
-        m.Load(kMachFloat64, m.PointerConstant(from), m.Int32Constant(offset));
-    m.Store(kMachFloat64, m.PointerConstant(to), m.Int32Constant(offset), load);
+    Node* load = m.Load(MachineType::Float64(), m.PointerConstant(from),
+                        m.IntPtrConstant(offset));
+    m.Store(MachineRepresentation::kFloat64, m.PointerConstant(to),
+            m.IntPtrConstant(offset), load, kNoWriteBarrier);
     m.Return(m.Int32Constant(magic));
 
     FOR_FLOAT64_INPUTS(j) {
       p1 = *j;
       p2 = *j - 5;
       CHECK_EQ(magic, m.Call());
-      CHECK_EQ(p1, p2);
+      CheckDoubleEq(p1, p2);
     }
   }
 }
@@ -529,7 +1211,8 @@
 
 TEST(RunInt32AddAndWord32EqualP) {
   {
-    RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32, kMachInt32);
+    RawMachineAssemblerTester<int32_t> m(
+        MachineType::Int32(), MachineType::Int32(), MachineType::Int32());
     m.Return(m.Int32Add(m.Parameter(0),
                         m.Word32Equal(m.Parameter(1), m.Parameter(2))));
     FOR_INT32_INPUTS(i) {
@@ -544,7 +1227,8 @@
     }
   }
   {
-    RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32, kMachInt32);
+    RawMachineAssemblerTester<int32_t> m(
+        MachineType::Int32(), MachineType::Int32(), MachineType::Int32());
     m.Return(m.Int32Add(m.Word32Equal(m.Parameter(0), m.Parameter(1)),
                         m.Parameter(2)));
     FOR_INT32_INPUTS(i) {
@@ -564,7 +1248,8 @@
 TEST(RunInt32AddAndWord32EqualImm) {
   {
     FOR_INT32_INPUTS(i) {
-      RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32);
+      RawMachineAssemblerTester<int32_t> m(MachineType::Int32(),
+                                           MachineType::Int32());
       m.Return(m.Int32Add(m.Int32Constant(*i),
                           m.Word32Equal(m.Parameter(0), m.Parameter(1))));
       FOR_INT32_INPUTS(j) {
@@ -579,7 +1264,8 @@
   }
   {
     FOR_INT32_INPUTS(i) {
-      RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32);
+      RawMachineAssemblerTester<int32_t> m(MachineType::Int32(),
+                                           MachineType::Int32());
       m.Return(m.Int32Add(m.Word32Equal(m.Int32Constant(*i), m.Parameter(0)),
                           m.Parameter(1)));
       FOR_INT32_INPUTS(j) {
@@ -597,7 +1283,8 @@
 
 TEST(RunInt32AddAndWord32NotEqualP) {
   {
-    RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32, kMachInt32);
+    RawMachineAssemblerTester<int32_t> m(
+        MachineType::Int32(), MachineType::Int32(), MachineType::Int32());
     m.Return(m.Int32Add(m.Parameter(0),
                         m.Word32NotEqual(m.Parameter(1), m.Parameter(2))));
     FOR_INT32_INPUTS(i) {
@@ -612,7 +1299,8 @@
     }
   }
   {
-    RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32, kMachInt32);
+    RawMachineAssemblerTester<int32_t> m(
+        MachineType::Int32(), MachineType::Int32(), MachineType::Int32());
     m.Return(m.Int32Add(m.Word32NotEqual(m.Parameter(0), m.Parameter(1)),
                         m.Parameter(2)));
     FOR_INT32_INPUTS(i) {
@@ -632,7 +1320,8 @@
 TEST(RunInt32AddAndWord32NotEqualImm) {
   {
     FOR_INT32_INPUTS(i) {
-      RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32);
+      RawMachineAssemblerTester<int32_t> m(MachineType::Int32(),
+                                           MachineType::Int32());
       m.Return(m.Int32Add(m.Int32Constant(*i),
                           m.Word32NotEqual(m.Parameter(0), m.Parameter(1))));
       FOR_INT32_INPUTS(j) {
@@ -647,7 +1336,8 @@
   }
   {
     FOR_INT32_INPUTS(i) {
-      RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32);
+      RawMachineAssemblerTester<int32_t> m(MachineType::Int32(),
+                                           MachineType::Int32());
       m.Return(m.Int32Add(m.Word32NotEqual(m.Int32Constant(*i), m.Parameter(0)),
                           m.Parameter(1)));
       FOR_INT32_INPUTS(j) {
@@ -665,7 +1355,8 @@
 
 TEST(RunInt32AddAndWord32SarP) {
   {
-    RawMachineAssemblerTester<int32_t> m(kMachUint32, kMachInt32, kMachUint32);
+    RawMachineAssemblerTester<int32_t> m(
+        MachineType::Uint32(), MachineType::Int32(), MachineType::Uint32());
     m.Return(m.Int32Add(m.Parameter(0),
                         m.Word32Sar(m.Parameter(1), m.Parameter(2))));
     FOR_UINT32_INPUTS(i) {
@@ -679,7 +1370,8 @@
     }
   }
   {
-    RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachUint32, kMachUint32);
+    RawMachineAssemblerTester<int32_t> m(
+        MachineType::Int32(), MachineType::Uint32(), MachineType::Uint32());
     m.Return(m.Int32Add(m.Word32Sar(m.Parameter(0), m.Parameter(1)),
                         m.Parameter(2)));
     FOR_INT32_INPUTS(i) {
@@ -697,7 +1389,8 @@
 
 TEST(RunInt32AddAndWord32ShlP) {
   {
-    RawMachineAssemblerTester<int32_t> m(kMachUint32, kMachInt32, kMachUint32);
+    RawMachineAssemblerTester<int32_t> m(
+        MachineType::Uint32(), MachineType::Int32(), MachineType::Uint32());
     m.Return(m.Int32Add(m.Parameter(0),
                         m.Word32Shl(m.Parameter(1), m.Parameter(2))));
     FOR_UINT32_INPUTS(i) {
@@ -711,7 +1404,8 @@
     }
   }
   {
-    RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachUint32, kMachUint32);
+    RawMachineAssemblerTester<int32_t> m(
+        MachineType::Int32(), MachineType::Uint32(), MachineType::Uint32());
     m.Return(m.Int32Add(m.Word32Shl(m.Parameter(0), m.Parameter(1)),
                         m.Parameter(2)));
     FOR_INT32_INPUTS(i) {
@@ -729,7 +1423,8 @@
 
 TEST(RunInt32AddAndWord32ShrP) {
   {
-    RawMachineAssemblerTester<int32_t> m(kMachUint32, kMachUint32, kMachUint32);
+    RawMachineAssemblerTester<int32_t> m(
+        MachineType::Uint32(), MachineType::Uint32(), MachineType::Uint32());
     m.Return(m.Int32Add(m.Parameter(0),
                         m.Word32Shr(m.Parameter(1), m.Parameter(2))));
     FOR_UINT32_INPUTS(i) {
@@ -743,7 +1438,8 @@
     }
   }
   {
-    RawMachineAssemblerTester<int32_t> m(kMachUint32, kMachUint32, kMachUint32);
+    RawMachineAssemblerTester<int32_t> m(
+        MachineType::Uint32(), MachineType::Uint32(), MachineType::Uint32());
     m.Return(m.Int32Add(m.Word32Shr(m.Parameter(0), m.Parameter(1)),
                         m.Parameter(2)));
     FOR_UINT32_INPUTS(i) {
@@ -763,8 +1459,8 @@
   static const int32_t constant = 987654321;
   {
     RawMachineAssemblerTester<int32_t> m;
-    Uint32BinopTester bt(&m);
-    MLabel blocka, blockb;
+    Int32BinopTester bt(&m);
+    RawMachineLabel blocka, blockb;
     m.Branch(
         m.Word32Equal(m.Int32Add(bt.param0, bt.param1), m.Int32Constant(0)),
         &blocka, &blockb);
@@ -781,8 +1477,8 @@
   }
   {
     RawMachineAssemblerTester<int32_t> m;
-    Uint32BinopTester bt(&m);
-    MLabel blocka, blockb;
+    Int32BinopTester bt(&m);
+    RawMachineLabel blocka, blockb;
     m.Branch(
         m.Word32NotEqual(m.Int32Add(bt.param0, bt.param1), m.Int32Constant(0)),
         &blocka, &blockb);
@@ -799,8 +1495,8 @@
   }
   {
     FOR_UINT32_INPUTS(i) {
-      RawMachineAssemblerTester<uint32_t> m(kMachUint32);
-      MLabel blocka, blockb;
+      RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
+      RawMachineLabel blocka, blockb;
       m.Branch(m.Word32Equal(m.Int32Add(m.Int32Constant(*i), m.Parameter(0)),
                              m.Int32Constant(0)),
                &blocka, &blockb);
@@ -810,14 +1506,14 @@
       m.Return(m.Int32Constant(0 - constant));
       FOR_UINT32_INPUTS(j) {
         uint32_t expected = (*i + *j) == 0 ? constant : 0 - constant;
-        CHECK_UINT32_EQ(expected, m.Call(*j));
+        CHECK_EQ(expected, m.Call(*j));
       }
     }
   }
   {
     FOR_UINT32_INPUTS(i) {
-      RawMachineAssemblerTester<uint32_t> m(kMachUint32);
-      MLabel blocka, blockb;
+      RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
+      RawMachineLabel blocka, blockb;
       m.Branch(m.Word32NotEqual(m.Int32Add(m.Int32Constant(*i), m.Parameter(0)),
                                 m.Int32Constant(0)),
                &blocka, &blockb);
@@ -827,7 +1523,7 @@
       m.Return(m.Int32Constant(0 - constant));
       FOR_UINT32_INPUTS(j) {
         uint32_t expected = (*i + *j) != 0 ? constant : 0 - constant;
-        CHECK_UINT32_EQ(expected, m.Call(*j));
+        CHECK_EQ(expected, m.Call(*j));
       }
     }
   }
@@ -837,11 +1533,11 @@
                                m.machine()->Word32Shl(),
                                m.machine()->Word32Shr()};
     for (size_t n = 0; n < arraysize(shops); n++) {
-      RawMachineAssemblerTester<int32_t> m(kMachUint32, kMachInt32,
-                                           kMachUint32);
-      MLabel blocka, blockb;
+      RawMachineAssemblerTester<int32_t> m(
+          MachineType::Uint32(), MachineType::Int32(), MachineType::Uint32());
+      RawMachineLabel blocka, blockb;
       m.Branch(m.Word32Equal(m.Int32Add(m.Parameter(0),
-                                        m.NewNode(shops[n], m.Parameter(1),
+                                        m.AddNode(shops[n], m.Parameter(1),
                                                   m.Parameter(2))),
                              m.Int32Constant(0)),
                &blocka, &blockb);
@@ -885,7 +1581,7 @@
     FOR_UINT32_INPUTS(i) {
       FOR_UINT32_INPUTS(j) {
         uint32_t expected = (*i + *j) == 0;
-        CHECK_UINT32_EQ(expected, bt.call(*i, *j));
+        CHECK_EQ(expected, bt.call(*i, *j));
       }
     }
   }
@@ -897,29 +1593,29 @@
     FOR_UINT32_INPUTS(i) {
       FOR_UINT32_INPUTS(j) {
         uint32_t expected = (*i + *j) == 0;
-        CHECK_UINT32_EQ(expected, bt.call(*i, *j));
+        CHECK_EQ(expected, bt.call(*i, *j));
       }
     }
   }
   {
     FOR_UINT32_INPUTS(i) {
-      RawMachineAssemblerTester<uint32_t> m(kMachUint32);
+      RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
       m.Return(m.Word32Equal(m.Int32Add(m.Int32Constant(*i), m.Parameter(0)),
                              m.Int32Constant(0)));
       FOR_UINT32_INPUTS(j) {
         uint32_t expected = (*i + *j) == 0;
-        CHECK_UINT32_EQ(expected, m.Call(*j));
+        CHECK_EQ(expected, m.Call(*j));
       }
     }
   }
   {
     FOR_UINT32_INPUTS(i) {
-      RawMachineAssemblerTester<uint32_t> m(kMachUint32);
+      RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
       m.Return(m.Word32Equal(m.Int32Add(m.Parameter(0), m.Int32Constant(*i)),
                              m.Int32Constant(0)));
       FOR_UINT32_INPUTS(j) {
         uint32_t expected = (*j + *i) == 0;
-        CHECK_UINT32_EQ(expected, m.Call(*j));
+        CHECK_EQ(expected, m.Call(*j));
       }
     }
   }
@@ -929,11 +1625,11 @@
                                m.machine()->Word32Shl(),
                                m.machine()->Word32Shr()};
     for (size_t n = 0; n < arraysize(shops); n++) {
-      RawMachineAssemblerTester<int32_t> m(kMachUint32, kMachInt32,
-                                           kMachUint32);
+      RawMachineAssemblerTester<int32_t> m(
+          MachineType::Uint32(), MachineType::Int32(), MachineType::Uint32());
       m.Return(m.Word32Equal(
           m.Int32Add(m.Parameter(0),
-                     m.NewNode(shops[n], m.Parameter(1), m.Parameter(2))),
+                     m.AddNode(shops[n], m.Parameter(1), m.Parameter(2))),
           m.Int32Constant(0)));
       FOR_UINT32_INPUTS(i) {
         FOR_INT32_INPUTS(j) {
@@ -971,7 +1667,7 @@
   FOR_UINT32_INPUTS(i) {
     FOR_UINT32_INPUTS(j) {
       uint32_t expected = static_cast<int32_t>(*i - *j);
-      CHECK_UINT32_EQ(expected, bt.call(*i, *j));
+      CHECK_EQ(expected, bt.call(*i, *j));
     }
   }
 }
@@ -980,21 +1676,21 @@
 TEST(RunInt32SubImm) {
   {
     FOR_UINT32_INPUTS(i) {
-      RawMachineAssemblerTester<uint32_t> m(kMachUint32);
+      RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
       m.Return(m.Int32Sub(m.Int32Constant(*i), m.Parameter(0)));
       FOR_UINT32_INPUTS(j) {
         uint32_t expected = *i - *j;
-        CHECK_UINT32_EQ(expected, m.Call(*j));
+        CHECK_EQ(expected, m.Call(*j));
       }
     }
   }
   {
     FOR_UINT32_INPUTS(i) {
-      RawMachineAssemblerTester<uint32_t> m(kMachUint32);
+      RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
       m.Return(m.Int32Sub(m.Parameter(0), m.Int32Constant(*i)));
       FOR_UINT32_INPUTS(j) {
         uint32_t expected = *j - *i;
-        CHECK_UINT32_EQ(expected, m.Call(*j));
+        CHECK_EQ(expected, m.Call(*j));
       }
     }
   }
@@ -1003,7 +1699,8 @@
 
 TEST(RunInt32SubAndWord32SarP) {
   {
-    RawMachineAssemblerTester<int32_t> m(kMachUint32, kMachInt32, kMachUint32);
+    RawMachineAssemblerTester<int32_t> m(
+        MachineType::Uint32(), MachineType::Int32(), MachineType::Uint32());
     m.Return(m.Int32Sub(m.Parameter(0),
                         m.Word32Sar(m.Parameter(1), m.Parameter(2))));
     FOR_UINT32_INPUTS(i) {
@@ -1016,7 +1713,8 @@
     }
   }
   {
-    RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachUint32, kMachUint32);
+    RawMachineAssemblerTester<int32_t> m(
+        MachineType::Int32(), MachineType::Uint32(), MachineType::Uint32());
     m.Return(m.Int32Sub(m.Word32Sar(m.Parameter(0), m.Parameter(1)),
                         m.Parameter(2)));
     FOR_INT32_INPUTS(i) {
@@ -1033,7 +1731,8 @@
 
 TEST(RunInt32SubAndWord32ShlP) {
   {
-    RawMachineAssemblerTester<int32_t> m(kMachUint32, kMachInt32, kMachUint32);
+    RawMachineAssemblerTester<int32_t> m(
+        MachineType::Uint32(), MachineType::Int32(), MachineType::Uint32());
     m.Return(m.Int32Sub(m.Parameter(0),
                         m.Word32Shl(m.Parameter(1), m.Parameter(2))));
     FOR_UINT32_INPUTS(i) {
@@ -1046,7 +1745,8 @@
     }
   }
   {
-    RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachUint32, kMachUint32);
+    RawMachineAssemblerTester<int32_t> m(
+        MachineType::Int32(), MachineType::Uint32(), MachineType::Uint32());
     m.Return(m.Int32Sub(m.Word32Shl(m.Parameter(0), m.Parameter(1)),
                         m.Parameter(2)));
     FOR_INT32_INPUTS(i) {
@@ -1064,30 +1764,30 @@
 
 TEST(RunInt32SubAndWord32ShrP) {
   {
-    RawMachineAssemblerTester<uint32_t> m(kMachUint32, kMachUint32,
-                                          kMachUint32);
+    RawMachineAssemblerTester<uint32_t> m(
+        MachineType::Uint32(), MachineType::Uint32(), MachineType::Uint32());
     m.Return(m.Int32Sub(m.Parameter(0),
                         m.Word32Shr(m.Parameter(1), m.Parameter(2))));
     FOR_UINT32_INPUTS(i) {
       FOR_UINT32_INPUTS(j) {
         FOR_UINT32_SHIFTS(shift) {
           // Use uint32_t because signed overflow is UB in C.
-          int32_t expected = *i - (*j >> shift);
-          CHECK_UINT32_EQ(expected, m.Call(*i, *j, shift));
+          uint32_t expected = *i - (*j >> shift);
+          CHECK_EQ(expected, m.Call(*i, *j, shift));
         }
       }
     }
   }
   {
-    RawMachineAssemblerTester<uint32_t> m(kMachUint32, kMachUint32,
-                                          kMachUint32);
+    RawMachineAssemblerTester<uint32_t> m(
+        MachineType::Uint32(), MachineType::Uint32(), MachineType::Uint32());
     m.Return(m.Int32Sub(m.Word32Shr(m.Parameter(0), m.Parameter(1)),
                         m.Parameter(2)));
     FOR_UINT32_INPUTS(i) {
       FOR_UINT32_SHIFTS(shift) {
         FOR_UINT32_INPUTS(k) {
           // Use uint32_t because signed overflow is UB in C.
-          int32_t expected = (*i >> shift) - *k;
+          uint32_t expected = (*i >> shift) - *k;
           CHECK_EQ(expected, m.Call(*i, shift, *k));
         }
       }
@@ -1100,8 +1800,8 @@
   static const int constant = 987654321;
   {
     RawMachineAssemblerTester<int32_t> m;
-    Uint32BinopTester bt(&m);
-    MLabel blocka, blockb;
+    Int32BinopTester bt(&m);
+    RawMachineLabel blocka, blockb;
     m.Branch(
         m.Word32Equal(m.Int32Sub(bt.param0, bt.param1), m.Int32Constant(0)),
         &blocka, &blockb);
@@ -1118,8 +1818,8 @@
   }
   {
     RawMachineAssemblerTester<int32_t> m;
-    Uint32BinopTester bt(&m);
-    MLabel blocka, blockb;
+    Int32BinopTester bt(&m);
+    RawMachineLabel blocka, blockb;
     m.Branch(
         m.Word32NotEqual(m.Int32Sub(bt.param0, bt.param1), m.Int32Constant(0)),
         &blocka, &blockb);
@@ -1136,8 +1836,8 @@
   }
   {
     FOR_UINT32_INPUTS(i) {
-      RawMachineAssemblerTester<uint32_t> m(kMachUint32);
-      MLabel blocka, blockb;
+      RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
+      RawMachineLabel blocka, blockb;
       m.Branch(m.Word32Equal(m.Int32Sub(m.Int32Constant(*i), m.Parameter(0)),
                              m.Int32Constant(0)),
                &blocka, &blockb);
@@ -1146,15 +1846,15 @@
       m.Bind(&blockb);
       m.Return(m.Int32Constant(0 - constant));
       FOR_UINT32_INPUTS(j) {
-        int32_t expected = (*i - *j) == 0 ? constant : 0 - constant;
+        uint32_t expected = (*i - *j) == 0 ? constant : 0 - constant;
         CHECK_EQ(expected, m.Call(*j));
       }
     }
   }
   {
     FOR_UINT32_INPUTS(i) {
-      RawMachineAssemblerTester<int32_t> m(kMachUint32);
-      MLabel blocka, blockb;
+      RawMachineAssemblerTester<int32_t> m(MachineType::Uint32());
+      RawMachineLabel blocka, blockb;
       m.Branch(m.Word32NotEqual(m.Int32Sub(m.Int32Constant(*i), m.Parameter(0)),
                                 m.Int32Constant(0)),
                &blocka, &blockb);
@@ -1174,11 +1874,11 @@
                                m.machine()->Word32Shl(),
                                m.machine()->Word32Shr()};
     for (size_t n = 0; n < arraysize(shops); n++) {
-      RawMachineAssemblerTester<int32_t> m(kMachUint32, kMachInt32,
-                                           kMachUint32);
-      MLabel blocka, blockb;
+      RawMachineAssemblerTester<int32_t> m(
+          MachineType::Uint32(), MachineType::Int32(), MachineType::Uint32());
+      RawMachineLabel blocka, blockb;
       m.Branch(m.Word32Equal(m.Int32Sub(m.Parameter(0),
-                                        m.NewNode(shops[n], m.Parameter(1),
+                                        m.AddNode(shops[n], m.Parameter(1),
                                                   m.Parameter(2))),
                              m.Int32Constant(0)),
                &blocka, &blockb);
@@ -1222,7 +1922,7 @@
     FOR_UINT32_INPUTS(i) {
       FOR_UINT32_INPUTS(j) {
         uint32_t expected = (*i - *j) == 0;
-        CHECK_UINT32_EQ(expected, bt.call(*i, *j));
+        CHECK_EQ(expected, bt.call(*i, *j));
       }
     }
   }
@@ -1234,29 +1934,29 @@
     FOR_UINT32_INPUTS(i) {
       FOR_UINT32_INPUTS(j) {
         uint32_t expected = (*i - *j) == 0;
-        CHECK_UINT32_EQ(expected, bt.call(*i, *j));
+        CHECK_EQ(expected, bt.call(*i, *j));
       }
     }
   }
   {
     FOR_UINT32_INPUTS(i) {
-      RawMachineAssemblerTester<uint32_t> m(kMachUint32);
+      RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
       m.Return(m.Word32Equal(m.Int32Sub(m.Int32Constant(*i), m.Parameter(0)),
                              m.Int32Constant(0)));
       FOR_UINT32_INPUTS(j) {
         uint32_t expected = (*i - *j) == 0;
-        CHECK_UINT32_EQ(expected, m.Call(*j));
+        CHECK_EQ(expected, m.Call(*j));
       }
     }
   }
   {
     FOR_UINT32_INPUTS(i) {
-      RawMachineAssemblerTester<uint32_t> m(kMachUint32);
+      RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
       m.Return(m.Word32Equal(m.Int32Sub(m.Parameter(0), m.Int32Constant(*i)),
                              m.Int32Constant(0)));
       FOR_UINT32_INPUTS(j) {
         uint32_t expected = (*j - *i) == 0;
-        CHECK_UINT32_EQ(expected, m.Call(*j));
+        CHECK_EQ(expected, m.Call(*j));
       }
     }
   }
@@ -1266,11 +1966,11 @@
                                m.machine()->Word32Shl(),
                                m.machine()->Word32Shr()};
     for (size_t n = 0; n < arraysize(shops); n++) {
-      RawMachineAssemblerTester<int32_t> m(kMachUint32, kMachInt32,
-                                           kMachUint32);
+      RawMachineAssemblerTester<int32_t> m(
+          MachineType::Uint32(), MachineType::Int32(), MachineType::Uint32());
       m.Return(m.Word32Equal(
           m.Int32Sub(m.Parameter(0),
-                     m.NewNode(shops[n], m.Parameter(1), m.Parameter(2))),
+                     m.AddNode(shops[n], m.Parameter(1), m.Parameter(2))),
           m.Int32Constant(0)));
       FOR_UINT32_INPUTS(i) {
         FOR_INT32_INPUTS(j) {
@@ -1318,7 +2018,7 @@
     FOR_UINT32_INPUTS(i) {
       FOR_UINT32_INPUTS(j) {
         uint32_t expected = *i * *j;
-        CHECK_UINT32_EQ(expected, bt.call(*i, *j));
+        CHECK_EQ(expected, bt.call(*i, *j));
       }
     }
   }
@@ -1342,21 +2042,21 @@
 TEST(RunInt32MulImm) {
   {
     FOR_UINT32_INPUTS(i) {
-      RawMachineAssemblerTester<uint32_t> m(kMachUint32);
+      RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
       m.Return(m.Int32Mul(m.Int32Constant(*i), m.Parameter(0)));
       FOR_UINT32_INPUTS(j) {
         uint32_t expected = *i * *j;
-        CHECK_UINT32_EQ(expected, m.Call(*j));
+        CHECK_EQ(expected, m.Call(*j));
       }
     }
   }
   {
     FOR_UINT32_INPUTS(i) {
-      RawMachineAssemblerTester<uint32_t> m(kMachUint32);
+      RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
       m.Return(m.Int32Mul(m.Parameter(0), m.Int32Constant(*i)));
       FOR_UINT32_INPUTS(j) {
         uint32_t expected = *j * *i;
-        CHECK_UINT32_EQ(expected, m.Call(*j));
+        CHECK_EQ(expected, m.Call(*j));
       }
     }
   }
@@ -1367,7 +2067,7 @@
   {
     FOR_INT32_INPUTS(i) {
       FOR_INT32_INPUTS(j) {
-        RawMachineAssemblerTester<int32_t> m(kMachInt32);
+        RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
         int32_t p0 = *i;
         int32_t p1 = *j;
         m.Return(m.Int32Add(m.Int32Constant(p0),
@@ -1381,7 +2081,8 @@
     }
   }
   {
-    RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32, kMachInt32);
+    RawMachineAssemblerTester<int32_t> m(
+        MachineType::Int32(), MachineType::Int32(), MachineType::Int32());
     m.Return(
         m.Int32Add(m.Parameter(0), m.Int32Mul(m.Parameter(1), m.Parameter(2))));
     FOR_INT32_INPUTS(i) {
@@ -1397,7 +2098,8 @@
     }
   }
   {
-    RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32, kMachInt32);
+    RawMachineAssemblerTester<int32_t> m(
+        MachineType::Int32(), MachineType::Int32(), MachineType::Int32());
     m.Return(
         m.Int32Add(m.Int32Mul(m.Parameter(0), m.Parameter(1)), m.Parameter(2)));
     FOR_INT32_INPUTS(i) {
@@ -1433,7 +2135,8 @@
 
 TEST(RunInt32MulAndInt32SubP) {
   {
-    RawMachineAssemblerTester<int32_t> m(kMachUint32, kMachInt32, kMachInt32);
+    RawMachineAssemblerTester<int32_t> m(
+        MachineType::Uint32(), MachineType::Int32(), MachineType::Int32());
     m.Return(
         m.Int32Sub(m.Parameter(0), m.Int32Mul(m.Parameter(1), m.Parameter(2))));
     FOR_UINT32_INPUTS(i) {
@@ -1527,7 +2230,7 @@
         uint32_t p0 = *i;
         uint32_t p1 = *j;
         if (p1 != 0) {
-          uint32_t expected = static_cast<uint32_t>(p0 / p1);
+          int32_t expected = bit_cast<int32_t>(p0 / p1);
           CHECK_EQ(expected, bt.call(p0, p1));
         }
       }
@@ -1542,7 +2245,7 @@
         uint32_t p0 = *i;
         uint32_t p1 = *j;
         if (p1 != 0) {
-          uint32_t expected = static_cast<uint32_t>(p0 + (p0 / p1));
+          int32_t expected = bit_cast<int32_t>(p0 + (p0 / p1));
           CHECK_EQ(expected, bt.call(p0, p1));
         }
       }
@@ -1588,7 +2291,7 @@
 TEST(RunUint32ModP) {
   {
     RawMachineAssemblerTester<int32_t> m;
-    Int32BinopTester bt(&m);
+    Uint32BinopTester bt(&m);
     bt.AddReturn(m.Uint32Mod(bt.param0, bt.param1));
     FOR_UINT32_INPUTS(i) {
       FOR_UINT32_INPUTS(j) {
@@ -1603,7 +2306,7 @@
   }
   {
     RawMachineAssemblerTester<int32_t> m;
-    Int32BinopTester bt(&m);
+    Uint32BinopTester bt(&m);
     bt.AddReturn(m.Int32Add(bt.param0, m.Uint32Mod(bt.param0, bt.param1)));
     FOR_UINT32_INPUTS(i) {
       FOR_UINT32_INPUTS(j) {
@@ -1626,7 +2329,7 @@
     bt.AddReturn(m.Word32And(bt.param0, bt.param1));
     FOR_UINT32_INPUTS(i) {
       FOR_UINT32_INPUTS(j) {
-        uint32_t expected = *i & *j;
+        int32_t expected = *i & *j;
         CHECK_EQ(expected, bt.call(*i, *j));
       }
     }
@@ -1637,7 +2340,7 @@
     bt.AddReturn(m.Word32And(bt.param0, m.Word32Not(bt.param1)));
     FOR_UINT32_INPUTS(i) {
       FOR_UINT32_INPUTS(j) {
-        uint32_t expected = *i & ~(*j);
+        int32_t expected = *i & ~(*j);
         CHECK_EQ(expected, bt.call(*i, *j));
       }
     }
@@ -1648,7 +2351,7 @@
     bt.AddReturn(m.Word32And(m.Word32Not(bt.param0), bt.param1));
     FOR_UINT32_INPUTS(i) {
       FOR_UINT32_INPUTS(j) {
-        uint32_t expected = ~(*i) & *j;
+        int32_t expected = ~(*i) & *j;
         CHECK_EQ(expected, bt.call(*i, *j));
       }
     }
@@ -1665,7 +2368,7 @@
     FOR_UINT32_INPUTS(i) {
       FOR_UINT32_INPUTS(j) {
         uint32_t expected = *i << (*j & 0x1f);
-        CHECK_UINT32_EQ(expected, bt.call(*i, *j));
+        CHECK_EQ(expected, bt.call(*i, *j));
       }
     }
   }
@@ -1677,7 +2380,7 @@
     FOR_UINT32_INPUTS(i) {
       FOR_UINT32_INPUTS(j) {
         uint32_t expected = *i << (0x1f & *j);
-        CHECK_UINT32_EQ(expected, bt.call(*i, *j));
+        CHECK_EQ(expected, bt.call(*i, *j));
       }
     }
   }
@@ -1693,7 +2396,7 @@
     FOR_UINT32_INPUTS(i) {
       FOR_UINT32_INPUTS(j) {
         uint32_t expected = *i >> (*j & 0x1f);
-        CHECK_UINT32_EQ(expected, bt.call(*i, *j));
+        CHECK_EQ(expected, bt.call(*i, *j));
       }
     }
   }
@@ -1705,7 +2408,7 @@
     FOR_UINT32_INPUTS(i) {
       FOR_UINT32_INPUTS(j) {
         uint32_t expected = *i >> (0x1f & *j);
-        CHECK_UINT32_EQ(expected, bt.call(*i, *j));
+        CHECK_EQ(expected, bt.call(*i, *j));
       }
     }
   }
@@ -1732,7 +2435,7 @@
         m.Word32Sar(bt.param0, m.Word32And(m.Int32Constant(0x1f), bt.param1)));
     FOR_INT32_INPUTS(i) {
       FOR_INT32_INPUTS(j) {
-        uint32_t expected = *i >> (0x1f & *j);
+        int32_t expected = *i >> (0x1f & *j);
         CHECK_EQ(expected, bt.call(*i, *j));
       }
     }
@@ -1743,21 +2446,21 @@
 TEST(RunWord32AndImm) {
   {
     FOR_UINT32_INPUTS(i) {
-      RawMachineAssemblerTester<uint32_t> m(kMachUint32);
+      RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
       m.Return(m.Word32And(m.Int32Constant(*i), m.Parameter(0)));
       FOR_UINT32_INPUTS(j) {
         uint32_t expected = *i & *j;
-        CHECK_UINT32_EQ(expected, m.Call(*j));
+        CHECK_EQ(expected, m.Call(*j));
       }
     }
   }
   {
     FOR_UINT32_INPUTS(i) {
-      RawMachineAssemblerTester<uint32_t> m(kMachUint32);
+      RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
       m.Return(m.Word32And(m.Int32Constant(*i), m.Word32Not(m.Parameter(0))));
       FOR_UINT32_INPUTS(j) {
         uint32_t expected = *i & ~(*j);
-        CHECK_UINT32_EQ(expected, m.Call(*j));
+        CHECK_EQ(expected, m.Call(*j));
       }
     }
   }
@@ -1768,8 +2471,8 @@
   static const int constant = 987654321;
   {
     RawMachineAssemblerTester<int32_t> m;
-    Uint32BinopTester bt(&m);
-    MLabel blocka, blockb;
+    Int32BinopTester bt(&m);
+    RawMachineLabel blocka, blockb;
     m.Branch(
         m.Word32Equal(m.Word32And(bt.param0, bt.param1), m.Int32Constant(0)),
         &blocka, &blockb);
@@ -1786,8 +2489,8 @@
   }
   {
     RawMachineAssemblerTester<int32_t> m;
-    Uint32BinopTester bt(&m);
-    MLabel blocka, blockb;
+    Int32BinopTester bt(&m);
+    RawMachineLabel blocka, blockb;
     m.Branch(
         m.Word32NotEqual(m.Word32And(bt.param0, bt.param1), m.Int32Constant(0)),
         &blocka, &blockb);
@@ -1804,8 +2507,8 @@
   }
   {
     FOR_UINT32_INPUTS(i) {
-      RawMachineAssemblerTester<int32_t> m(kMachUint32);
-      MLabel blocka, blockb;
+      RawMachineAssemblerTester<int32_t> m(MachineType::Uint32());
+      RawMachineLabel blocka, blockb;
       m.Branch(m.Word32Equal(m.Word32And(m.Int32Constant(*i), m.Parameter(0)),
                              m.Int32Constant(0)),
                &blocka, &blockb);
@@ -1821,8 +2524,8 @@
   }
   {
     FOR_UINT32_INPUTS(i) {
-      RawMachineAssemblerTester<int32_t> m(kMachUint32);
-      MLabel blocka, blockb;
+      RawMachineAssemblerTester<int32_t> m(MachineType::Uint32());
+      RawMachineLabel blocka, blockb;
       m.Branch(
           m.Word32NotEqual(m.Word32And(m.Int32Constant(*i), m.Parameter(0)),
                            m.Int32Constant(0)),
@@ -1843,11 +2546,11 @@
                                m.machine()->Word32Shl(),
                                m.machine()->Word32Shr()};
     for (size_t n = 0; n < arraysize(shops); n++) {
-      RawMachineAssemblerTester<int32_t> m(kMachUint32, kMachInt32,
-                                           kMachUint32);
-      MLabel blocka, blockb;
+      RawMachineAssemblerTester<int32_t> m(
+          MachineType::Uint32(), MachineType::Int32(), MachineType::Uint32());
+      RawMachineLabel blocka, blockb;
       m.Branch(m.Word32Equal(m.Word32And(m.Parameter(0),
-                                         m.NewNode(shops[n], m.Parameter(1),
+                                         m.AddNode(shops[n], m.Parameter(1),
                                                    m.Parameter(2))),
                              m.Int32Constant(0)),
                &blocka, &blockb);
@@ -1891,7 +2594,7 @@
     FOR_UINT32_INPUTS(i) {
       FOR_UINT32_INPUTS(j) {
         uint32_t expected = (*i & *j) == 0;
-        CHECK_UINT32_EQ(expected, bt.call(*i, *j));
+        CHECK_EQ(expected, bt.call(*i, *j));
       }
     }
   }
@@ -1903,29 +2606,29 @@
     FOR_UINT32_INPUTS(i) {
       FOR_UINT32_INPUTS(j) {
         uint32_t expected = (*i & *j) == 0;
-        CHECK_UINT32_EQ(expected, bt.call(*i, *j));
+        CHECK_EQ(expected, bt.call(*i, *j));
       }
     }
   }
   {
     FOR_UINT32_INPUTS(i) {
-      RawMachineAssemblerTester<uint32_t> m(kMachUint32);
+      RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
       m.Return(m.Word32Equal(m.Word32And(m.Int32Constant(*i), m.Parameter(0)),
                              m.Int32Constant(0)));
       FOR_UINT32_INPUTS(j) {
         uint32_t expected = (*i & *j) == 0;
-        CHECK_UINT32_EQ(expected, m.Call(*j));
+        CHECK_EQ(expected, m.Call(*j));
       }
     }
   }
   {
     FOR_UINT32_INPUTS(i) {
-      RawMachineAssemblerTester<uint32_t> m(kMachUint32);
+      RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
       m.Return(m.Word32Equal(m.Word32And(m.Parameter(0), m.Int32Constant(*i)),
                              m.Int32Constant(0)));
       FOR_UINT32_INPUTS(j) {
         uint32_t expected = (*j & *i) == 0;
-        CHECK_UINT32_EQ(expected, m.Call(*j));
+        CHECK_EQ(expected, m.Call(*j));
       }
     }
   }
@@ -1940,7 +2643,7 @@
     FOR_UINT32_INPUTS(i) {
       FOR_UINT32_INPUTS(j) {
         uint32_t expected = *i | *j;
-        CHECK_UINT32_EQ(expected, bt.call(*i, *j));
+        CHECK_EQ(expected, bt.call(*i, *j));
       }
     }
   }
@@ -1951,7 +2654,7 @@
     FOR_UINT32_INPUTS(i) {
       FOR_UINT32_INPUTS(j) {
         uint32_t expected = *i | ~(*j);
-        CHECK_UINT32_EQ(expected, bt.call(*i, *j));
+        CHECK_EQ(expected, bt.call(*i, *j));
       }
     }
   }
@@ -1962,7 +2665,7 @@
     FOR_UINT32_INPUTS(i) {
       FOR_UINT32_INPUTS(j) {
         uint32_t expected = ~(*i) | *j;
-        CHECK_UINT32_EQ(expected, bt.call(*i, *j));
+        CHECK_EQ(expected, bt.call(*i, *j));
       }
     }
   }
@@ -1972,21 +2675,21 @@
 TEST(RunWord32OrImm) {
   {
     FOR_UINT32_INPUTS(i) {
-      RawMachineAssemblerTester<uint32_t> m(kMachUint32);
+      RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
       m.Return(m.Word32Or(m.Int32Constant(*i), m.Parameter(0)));
       FOR_UINT32_INPUTS(j) {
         uint32_t expected = *i | *j;
-        CHECK_UINT32_EQ(expected, m.Call(*j));
+        CHECK_EQ(expected, m.Call(*j));
       }
     }
   }
   {
     FOR_UINT32_INPUTS(i) {
-      RawMachineAssemblerTester<uint32_t> m(kMachUint32);
+      RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
       m.Return(m.Word32Or(m.Int32Constant(*i), m.Word32Not(m.Parameter(0))));
       FOR_UINT32_INPUTS(j) {
         uint32_t expected = *i | ~(*j);
-        CHECK_UINT32_EQ(expected, m.Call(*j));
+        CHECK_EQ(expected, m.Call(*j));
       }
     }
   }
@@ -1998,7 +2701,7 @@
   {
     RawMachineAssemblerTester<int32_t> m;
     Int32BinopTester bt(&m);
-    MLabel blocka, blockb;
+    RawMachineLabel blocka, blockb;
     m.Branch(
         m.Word32Equal(m.Word32Or(bt.param0, bt.param1), m.Int32Constant(0)),
         &blocka, &blockb);
@@ -2016,7 +2719,7 @@
   {
     RawMachineAssemblerTester<int32_t> m;
     Int32BinopTester bt(&m);
-    MLabel blocka, blockb;
+    RawMachineLabel blocka, blockb;
     m.Branch(
         m.Word32NotEqual(m.Word32Or(bt.param0, bt.param1), m.Int32Constant(0)),
         &blocka, &blockb);
@@ -2033,8 +2736,8 @@
   }
   {
     FOR_INT32_INPUTS(i) {
-      RawMachineAssemblerTester<int32_t> m(kMachInt32);
-      MLabel blocka, blockb;
+      RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
+      RawMachineLabel blocka, blockb;
       m.Branch(m.Word32Equal(m.Word32Or(m.Int32Constant(*i), m.Parameter(0)),
                              m.Int32Constant(0)),
                &blocka, &blockb);
@@ -2050,8 +2753,8 @@
   }
   {
     FOR_INT32_INPUTS(i) {
-      RawMachineAssemblerTester<int32_t> m(kMachInt32);
-      MLabel blocka, blockb;
+      RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
+      RawMachineLabel blocka, blockb;
       m.Branch(m.Word32NotEqual(m.Word32Or(m.Int32Constant(*i), m.Parameter(0)),
                                 m.Int32Constant(0)),
                &blocka, &blockb);
@@ -2071,11 +2774,11 @@
                                m.machine()->Word32Shl(),
                                m.machine()->Word32Shr()};
     for (size_t n = 0; n < arraysize(shops); n++) {
-      RawMachineAssemblerTester<int32_t> m(kMachUint32, kMachInt32,
-                                           kMachUint32);
-      MLabel blocka, blockb;
+      RawMachineAssemblerTester<int32_t> m(
+          MachineType::Uint32(), MachineType::Int32(), MachineType::Uint32());
+      RawMachineLabel blocka, blockb;
       m.Branch(m.Word32Equal(m.Word32Or(m.Parameter(0),
-                                        m.NewNode(shops[n], m.Parameter(1),
+                                        m.AddNode(shops[n], m.Parameter(1),
                                                   m.Parameter(2))),
                              m.Int32Constant(0)),
                &blocka, &blockb);
@@ -2113,7 +2816,7 @@
 TEST(RunWord32OrInComparison) {
   {
     RawMachineAssemblerTester<int32_t> m;
-    Uint32BinopTester bt(&m);
+    Int32BinopTester bt(&m);
     bt.AddReturn(
         m.Word32Equal(m.Word32Or(bt.param0, bt.param1), m.Int32Constant(0)));
     FOR_UINT32_INPUTS(i) {
@@ -2125,7 +2828,7 @@
   }
   {
     RawMachineAssemblerTester<int32_t> m;
-    Uint32BinopTester bt(&m);
+    Int32BinopTester bt(&m);
     bt.AddReturn(
         m.Word32Equal(m.Int32Constant(0), m.Word32Or(bt.param0, bt.param1)));
     FOR_UINT32_INPUTS(i) {
@@ -2137,23 +2840,23 @@
   }
   {
     FOR_UINT32_INPUTS(i) {
-      RawMachineAssemblerTester<uint32_t> m(kMachUint32);
+      RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
       m.Return(m.Word32Equal(m.Word32Or(m.Int32Constant(*i), m.Parameter(0)),
                              m.Int32Constant(0)));
       FOR_UINT32_INPUTS(j) {
         uint32_t expected = (*i | *j) == 0;
-        CHECK_UINT32_EQ(expected, m.Call(*j));
+        CHECK_EQ(expected, m.Call(*j));
       }
     }
   }
   {
     FOR_UINT32_INPUTS(i) {
-      RawMachineAssemblerTester<uint32_t> m(kMachUint32);
+      RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
       m.Return(m.Word32Equal(m.Word32Or(m.Parameter(0), m.Int32Constant(*i)),
                              m.Int32Constant(0)));
       FOR_UINT32_INPUTS(j) {
         uint32_t expected = (*j | *i) == 0;
-        CHECK_UINT32_EQ(expected, m.Call(*j));
+        CHECK_EQ(expected, m.Call(*j));
       }
     }
   }
@@ -2163,11 +2866,11 @@
 TEST(RunWord32XorP) {
   {
     FOR_UINT32_INPUTS(i) {
-      RawMachineAssemblerTester<int32_t> m(kMachUint32);
+      RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
       m.Return(m.Word32Xor(m.Int32Constant(*i), m.Parameter(0)));
       FOR_UINT32_INPUTS(j) {
         uint32_t expected = *i ^ *j;
-        CHECK_UINT32_EQ(expected, m.Call(*j));
+        CHECK_EQ(expected, m.Call(*j));
       }
     }
   }
@@ -2177,8 +2880,8 @@
     bt.AddReturn(m.Word32Xor(bt.param0, bt.param1));
     FOR_UINT32_INPUTS(i) {
       FOR_UINT32_INPUTS(j) {
-        int32_t expected = *i ^ *j;
-        CHECK_UINT32_EQ(expected, bt.call(*i, *j));
+        uint32_t expected = *i ^ *j;
+        CHECK_EQ(expected, bt.call(*i, *j));
       }
     }
   }
@@ -2206,11 +2909,11 @@
   }
   {
     FOR_UINT32_INPUTS(i) {
-      RawMachineAssemblerTester<uint32_t> m(kMachUint32);
+      RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
       m.Return(m.Word32Xor(m.Int32Constant(*i), m.Word32Not(m.Parameter(0))));
       FOR_UINT32_INPUTS(j) {
         uint32_t expected = *i ^ ~(*j);
-        CHECK_UINT32_EQ(expected, m.Call(*j));
+        CHECK_EQ(expected, m.Call(*j));
       }
     }
   }
@@ -2222,7 +2925,7 @@
   {
     RawMachineAssemblerTester<int32_t> m;
     Uint32BinopTester bt(&m);
-    MLabel blocka, blockb;
+    RawMachineLabel blocka, blockb;
     m.Branch(
         m.Word32Equal(m.Word32Xor(bt.param0, bt.param1), m.Int32Constant(0)),
         &blocka, &blockb);
@@ -2233,14 +2936,14 @@
     FOR_UINT32_INPUTS(i) {
       FOR_UINT32_INPUTS(j) {
         uint32_t expected = (*i ^ *j) == 0 ? constant : 0 - constant;
-        CHECK_UINT32_EQ(expected, bt.call(*i, *j));
+        CHECK_EQ(expected, bt.call(*i, *j));
       }
     }
   }
   {
     RawMachineAssemblerTester<int32_t> m;
     Uint32BinopTester bt(&m);
-    MLabel blocka, blockb;
+    RawMachineLabel blocka, blockb;
     m.Branch(
         m.Word32NotEqual(m.Word32Xor(bt.param0, bt.param1), m.Int32Constant(0)),
         &blocka, &blockb);
@@ -2251,14 +2954,14 @@
     FOR_UINT32_INPUTS(i) {
       FOR_UINT32_INPUTS(j) {
         uint32_t expected = (*i ^ *j) != 0 ? constant : 0 - constant;
-        CHECK_UINT32_EQ(expected, bt.call(*i, *j));
+        CHECK_EQ(expected, bt.call(*i, *j));
       }
     }
   }
   {
     FOR_UINT32_INPUTS(i) {
-      RawMachineAssemblerTester<uint32_t> m(kMachUint32);
-      MLabel blocka, blockb;
+      RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
+      RawMachineLabel blocka, blockb;
       m.Branch(m.Word32Equal(m.Word32Xor(m.Int32Constant(*i), m.Parameter(0)),
                              m.Int32Constant(0)),
                &blocka, &blockb);
@@ -2268,14 +2971,14 @@
       m.Return(m.Int32Constant(0 - constant));
       FOR_UINT32_INPUTS(j) {
         uint32_t expected = (*i ^ *j) == 0 ? constant : 0 - constant;
-        CHECK_UINT32_EQ(expected, m.Call(*j));
+        CHECK_EQ(expected, m.Call(*j));
       }
     }
   }
   {
     FOR_UINT32_INPUTS(i) {
-      RawMachineAssemblerTester<uint32_t> m(kMachUint32);
-      MLabel blocka, blockb;
+      RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
+      RawMachineLabel blocka, blockb;
       m.Branch(
           m.Word32NotEqual(m.Word32Xor(m.Int32Constant(*i), m.Parameter(0)),
                            m.Int32Constant(0)),
@@ -2286,7 +2989,7 @@
       m.Return(m.Int32Constant(0 - constant));
       FOR_UINT32_INPUTS(j) {
         uint32_t expected = (*i ^ *j) != 0 ? constant : 0 - constant;
-        CHECK_UINT32_EQ(expected, m.Call(*j));
+        CHECK_EQ(expected, m.Call(*j));
       }
     }
   }
@@ -2296,11 +2999,11 @@
                                m.machine()->Word32Shl(),
                                m.machine()->Word32Shr()};
     for (size_t n = 0; n < arraysize(shops); n++) {
-      RawMachineAssemblerTester<int32_t> m(kMachUint32, kMachInt32,
-                                           kMachUint32);
-      MLabel blocka, blockb;
+      RawMachineAssemblerTester<int32_t> m(
+          MachineType::Uint32(), MachineType::Int32(), MachineType::Uint32());
+      RawMachineLabel blocka, blockb;
       m.Branch(m.Word32Equal(m.Word32Xor(m.Parameter(0),
-                                         m.NewNode(shops[n], m.Parameter(1),
+                                         m.AddNode(shops[n], m.Parameter(1),
                                                    m.Parameter(2))),
                              m.Int32Constant(0)),
                &blocka, &blockb);
@@ -2338,11 +3041,11 @@
 TEST(RunWord32ShlP) {
   {
     FOR_UINT32_SHIFTS(shift) {
-      RawMachineAssemblerTester<uint32_t> m(kMachUint32);
+      RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
       m.Return(m.Word32Shl(m.Parameter(0), m.Int32Constant(shift)));
       FOR_UINT32_INPUTS(j) {
         uint32_t expected = *j << shift;
-        CHECK_UINT32_EQ(expected, m.Call(*j));
+        CHECK_EQ(expected, m.Call(*j));
       }
     }
   }
@@ -2353,7 +3056,7 @@
     FOR_UINT32_INPUTS(i) {
       FOR_UINT32_SHIFTS(shift) {
         uint32_t expected = *i << shift;
-        CHECK_UINT32_EQ(expected, bt.call(*i, shift));
+        CHECK_EQ(expected, bt.call(*i, shift));
       }
     }
   }
@@ -2369,7 +3072,7 @@
     FOR_UINT32_INPUTS(i) {
       FOR_UINT32_SHIFTS(shift) {
         uint32_t expected = 0 == (*i << shift);
-        CHECK_UINT32_EQ(expected, bt.call(*i, shift));
+        CHECK_EQ(expected, bt.call(*i, shift));
       }
     }
   }
@@ -2381,31 +3084,31 @@
     FOR_UINT32_INPUTS(i) {
       FOR_UINT32_SHIFTS(shift) {
         uint32_t expected = 0 == (*i << shift);
-        CHECK_UINT32_EQ(expected, bt.call(*i, shift));
+        CHECK_EQ(expected, bt.call(*i, shift));
       }
     }
   }
   {
     FOR_UINT32_SHIFTS(shift) {
-      RawMachineAssemblerTester<int32_t> m(kMachUint32);
+      RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
       m.Return(
           m.Word32Equal(m.Int32Constant(0),
                         m.Word32Shl(m.Parameter(0), m.Int32Constant(shift))));
       FOR_UINT32_INPUTS(i) {
         uint32_t expected = 0 == (*i << shift);
-        CHECK_UINT32_EQ(expected, m.Call(*i));
+        CHECK_EQ(expected, m.Call(*i));
       }
     }
   }
   {
     FOR_UINT32_SHIFTS(shift) {
-      RawMachineAssemblerTester<int32_t> m(kMachUint32);
+      RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
       m.Return(
           m.Word32Equal(m.Word32Shl(m.Parameter(0), m.Int32Constant(shift)),
                         m.Int32Constant(0)));
       FOR_UINT32_INPUTS(i) {
         uint32_t expected = 0 == (*i << shift);
-        CHECK_UINT32_EQ(expected, m.Call(*i));
+        CHECK_EQ(expected, m.Call(*i));
       }
     }
   }
@@ -2415,11 +3118,11 @@
 TEST(RunWord32ShrP) {
   {
     FOR_UINT32_SHIFTS(shift) {
-      RawMachineAssemblerTester<uint32_t> m(kMachUint32);
+      RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
       m.Return(m.Word32Shr(m.Parameter(0), m.Int32Constant(shift)));
       FOR_UINT32_INPUTS(j) {
         uint32_t expected = *j >> shift;
-        CHECK_UINT32_EQ(expected, m.Call(*j));
+        CHECK_EQ(expected, m.Call(*j));
       }
     }
   }
@@ -2430,10 +3133,10 @@
     FOR_UINT32_INPUTS(i) {
       FOR_UINT32_SHIFTS(shift) {
         uint32_t expected = *i >> shift;
-        CHECK_UINT32_EQ(expected, bt.call(*i, shift));
+        CHECK_EQ(expected, bt.call(*i, shift));
       }
     }
-    CHECK_EQ(0x00010000, bt.call(0x80000000, 15));
+    CHECK_EQ(0x00010000u, bt.call(0x80000000, 15));
   }
 }
 
@@ -2447,7 +3150,7 @@
     FOR_UINT32_INPUTS(i) {
       FOR_UINT32_SHIFTS(shift) {
         uint32_t expected = 0 == (*i >> shift);
-        CHECK_UINT32_EQ(expected, bt.call(*i, shift));
+        CHECK_EQ(expected, bt.call(*i, shift));
       }
     }
   }
@@ -2459,31 +3162,31 @@
     FOR_UINT32_INPUTS(i) {
       FOR_UINT32_SHIFTS(shift) {
         uint32_t expected = 0 == (*i >> shift);
-        CHECK_UINT32_EQ(expected, bt.call(*i, shift));
+        CHECK_EQ(expected, bt.call(*i, shift));
       }
     }
   }
   {
     FOR_UINT32_SHIFTS(shift) {
-      RawMachineAssemblerTester<int32_t> m(kMachUint32);
+      RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
       m.Return(
           m.Word32Equal(m.Int32Constant(0),
                         m.Word32Shr(m.Parameter(0), m.Int32Constant(shift))));
       FOR_UINT32_INPUTS(i) {
         uint32_t expected = 0 == (*i >> shift);
-        CHECK_UINT32_EQ(expected, m.Call(*i));
+        CHECK_EQ(expected, m.Call(*i));
       }
     }
   }
   {
     FOR_UINT32_SHIFTS(shift) {
-      RawMachineAssemblerTester<int32_t> m(kMachUint32);
+      RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
       m.Return(
           m.Word32Equal(m.Word32Shr(m.Parameter(0), m.Int32Constant(shift)),
                         m.Int32Constant(0)));
       FOR_UINT32_INPUTS(i) {
         uint32_t expected = 0 == (*i >> shift);
-        CHECK_UINT32_EQ(expected, m.Call(*i));
+        CHECK_EQ(expected, m.Call(*i));
       }
     }
   }
@@ -2493,7 +3196,7 @@
 TEST(RunWord32SarP) {
   {
     FOR_INT32_SHIFTS(shift) {
-      RawMachineAssemblerTester<int32_t> m(kMachInt32);
+      RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
       m.Return(m.Word32Sar(m.Parameter(0), m.Int32Constant(shift)));
       FOR_INT32_INPUTS(j) {
         int32_t expected = *j >> shift;
@@ -2511,7 +3214,7 @@
         CHECK_EQ(expected, bt.call(*i, shift));
       }
     }
-    CHECK_EQ(0xFFFF0000, bt.call(0x80000000, 15));
+    CHECK_EQ(bit_cast<int32_t>(0xFFFF0000), bt.call(0x80000000, 15));
   }
 }
 
@@ -2543,7 +3246,7 @@
   }
   {
     FOR_INT32_SHIFTS(shift) {
-      RawMachineAssemblerTester<int32_t> m(kMachInt32);
+      RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
       m.Return(
           m.Word32Equal(m.Int32Constant(0),
                         m.Word32Sar(m.Parameter(0), m.Int32Constant(shift))));
@@ -2555,12 +3258,12 @@
   }
   {
     FOR_INT32_SHIFTS(shift) {
-      RawMachineAssemblerTester<int32_t> m(kMachInt32);
+      RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
       m.Return(
           m.Word32Equal(m.Word32Sar(m.Parameter(0), m.Int32Constant(shift)),
                         m.Int32Constant(0)));
       FOR_INT32_INPUTS(i) {
-        uint32_t expected = 0 == (*i >> shift);
+        int32_t expected = 0 == (*i >> shift);
         CHECK_EQ(expected, m.Call(*i));
       }
     }
@@ -2571,7 +3274,7 @@
 TEST(RunWord32RorP) {
   {
     FOR_UINT32_SHIFTS(shift) {
-      RawMachineAssemblerTester<int32_t> m(kMachUint32);
+      RawMachineAssemblerTester<int32_t> m(MachineType::Uint32());
       m.Return(m.Word32Ror(m.Parameter(0), m.Int32Constant(shift)));
       FOR_UINT32_INPUTS(j) {
         int32_t expected = bits::RotateRight32(*j, shift);
@@ -2586,7 +3289,7 @@
     FOR_UINT32_INPUTS(i) {
       FOR_UINT32_SHIFTS(shift) {
         uint32_t expected = bits::RotateRight32(*i, shift);
-        CHECK_UINT32_EQ(expected, bt.call(*i, shift));
+        CHECK_EQ(expected, bt.call(*i, shift));
       }
     }
   }
@@ -2602,7 +3305,7 @@
     FOR_UINT32_INPUTS(i) {
       FOR_UINT32_SHIFTS(shift) {
         uint32_t expected = 0 == bits::RotateRight32(*i, shift);
-        CHECK_UINT32_EQ(expected, bt.call(*i, shift));
+        CHECK_EQ(expected, bt.call(*i, shift));
       }
     }
   }
@@ -2614,31 +3317,31 @@
     FOR_UINT32_INPUTS(i) {
       FOR_UINT32_SHIFTS(shift) {
         uint32_t expected = 0 == bits::RotateRight32(*i, shift);
-        CHECK_UINT32_EQ(expected, bt.call(*i, shift));
+        CHECK_EQ(expected, bt.call(*i, shift));
       }
     }
   }
   {
     FOR_UINT32_SHIFTS(shift) {
-      RawMachineAssemblerTester<int32_t> m(kMachUint32);
+      RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
       m.Return(
           m.Word32Equal(m.Int32Constant(0),
                         m.Word32Ror(m.Parameter(0), m.Int32Constant(shift))));
       FOR_UINT32_INPUTS(i) {
         uint32_t expected = 0 == bits::RotateRight32(*i, shift);
-        CHECK_UINT32_EQ(expected, m.Call(*i));
+        CHECK_EQ(expected, m.Call(*i));
       }
     }
   }
   {
     FOR_UINT32_SHIFTS(shift) {
-      RawMachineAssemblerTester<int32_t> m(kMachUint32);
+      RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
       m.Return(
           m.Word32Equal(m.Word32Ror(m.Parameter(0), m.Int32Constant(shift)),
                         m.Int32Constant(0)));
       FOR_UINT32_INPUTS(i) {
         uint32_t expected = 0 == bits::RotateRight32(*i, shift);
-        CHECK_UINT32_EQ(expected, m.Call(*i));
+        CHECK_EQ(expected, m.Call(*i));
       }
     }
   }
@@ -2646,7 +3349,7 @@
 
 
 TEST(RunWord32NotP) {
-  RawMachineAssemblerTester<int32_t> m(kMachInt32);
+  RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
   m.Return(m.Word32Not(m.Parameter(0)));
   FOR_INT32_INPUTS(i) {
     int expected = ~(*i);
@@ -2656,7 +3359,7 @@
 
 
 TEST(RunInt32NegP) {
-  RawMachineAssemblerTester<int32_t> m(kMachInt32);
+  RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
   m.Return(m.Int32Neg(m.Parameter(0)));
   FOR_INT32_INPUTS(i) {
     int expected = -*i;
@@ -2667,7 +3370,8 @@
 
 TEST(RunWord32EqualAndWord32SarP) {
   {
-    RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32, kMachUint32);
+    RawMachineAssemblerTester<int32_t> m(
+        MachineType::Int32(), MachineType::Int32(), MachineType::Uint32());
     m.Return(m.Word32Equal(m.Parameter(0),
                            m.Word32Sar(m.Parameter(1), m.Parameter(2))));
     FOR_INT32_INPUTS(i) {
@@ -2680,7 +3384,8 @@
     }
   }
   {
-    RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachUint32, kMachInt32);
+    RawMachineAssemblerTester<int32_t> m(
+        MachineType::Int32(), MachineType::Uint32(), MachineType::Int32());
     m.Return(m.Word32Equal(m.Word32Sar(m.Parameter(0), m.Parameter(1)),
                            m.Parameter(2)));
     FOR_INT32_INPUTS(i) {
@@ -2697,7 +3402,8 @@
 
 TEST(RunWord32EqualAndWord32ShlP) {
   {
-    RawMachineAssemblerTester<int32_t> m(kMachUint32, kMachUint32, kMachUint32);
+    RawMachineAssemblerTester<int32_t> m(
+        MachineType::Uint32(), MachineType::Uint32(), MachineType::Uint32());
     m.Return(m.Word32Equal(m.Parameter(0),
                            m.Word32Shl(m.Parameter(1), m.Parameter(2))));
     FOR_UINT32_INPUTS(i) {
@@ -2710,7 +3416,8 @@
     }
   }
   {
-    RawMachineAssemblerTester<int32_t> m(kMachUint32, kMachUint32, kMachUint32);
+    RawMachineAssemblerTester<int32_t> m(
+        MachineType::Uint32(), MachineType::Uint32(), MachineType::Uint32());
     m.Return(m.Word32Equal(m.Word32Shl(m.Parameter(0), m.Parameter(1)),
                            m.Parameter(2)));
     FOR_UINT32_INPUTS(i) {
@@ -2727,7 +3434,8 @@
 
 TEST(RunWord32EqualAndWord32ShrP) {
   {
-    RawMachineAssemblerTester<int32_t> m(kMachUint32, kMachUint32, kMachUint32);
+    RawMachineAssemblerTester<int32_t> m(
+        MachineType::Uint32(), MachineType::Uint32(), MachineType::Uint32());
     m.Return(m.Word32Equal(m.Parameter(0),
                            m.Word32Shr(m.Parameter(1), m.Parameter(2))));
     FOR_UINT32_INPUTS(i) {
@@ -2740,7 +3448,8 @@
     }
   }
   {
-    RawMachineAssemblerTester<int32_t> m(kMachUint32, kMachUint32, kMachUint32);
+    RawMachineAssemblerTester<int32_t> m(
+        MachineType::Uint32(), MachineType::Uint32(), MachineType::Uint32());
     m.Return(m.Word32Equal(m.Word32Shr(m.Parameter(0), m.Parameter(1)),
                            m.Parameter(2)));
     FOR_UINT32_INPUTS(i) {
@@ -2757,7 +3466,8 @@
 
 TEST(RunDeadNodes) {
   for (int i = 0; true; i++) {
-    RawMachineAssemblerTester<int32_t> m(i == 5 ? kMachInt32 : kMachNone);
+    RawMachineAssemblerTester<int32_t> m(i == 5 ? MachineType::Int32()
+                                                : MachineType::None());
     int constant = 0x55 + i;
     switch (i) {
       case 0:
@@ -2773,7 +3483,7 @@
         m.PointerConstant(&constant);
         break;
       case 4:
-        m.LoadFromPointer(&constant, kMachInt32);
+        m.LoadFromPointer(&constant, MachineType::Int32());
         break;
       case 5:
         m.Parameter(0);
@@ -2808,9 +3518,10 @@
       m.machine()->Uint32LessThanOrEqual()};
 
   for (size_t i = 0; i < arraysize(kOps); ++i) {
-    RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32);
+    RawMachineAssemblerTester<int32_t> m(MachineType::Int32(),
+                                         MachineType::Int32());
     int32_t constant = static_cast<int32_t>(0x55555 + i);
-    m.NewNode(kOps[i], m.Parameter(0), m.Parameter(1));
+    m.AddNode(kOps[i], m.Parameter(0), m.Parameter(1));
     m.Return(m.Int32Constant(constant));
 
     CHECK_EQ(constant, m.Call(1, 1));
@@ -2846,16 +3557,16 @@
 
 
 TEST(RunLoadImmIndex) {
-  RunLoadImmIndex<int8_t>(kMachInt8);
-  RunLoadImmIndex<uint8_t>(kMachUint8);
-  RunLoadImmIndex<int16_t>(kMachInt16);
-  RunLoadImmIndex<uint16_t>(kMachUint16);
-  RunLoadImmIndex<int32_t>(kMachInt32);
-  RunLoadImmIndex<uint32_t>(kMachUint32);
-  RunLoadImmIndex<int32_t*>(kMachAnyTagged);
+  RunLoadImmIndex<int8_t>(MachineType::Int8());
+  RunLoadImmIndex<uint8_t>(MachineType::Uint8());
+  RunLoadImmIndex<int16_t>(MachineType::Int16());
+  RunLoadImmIndex<uint16_t>(MachineType::Uint16());
+  RunLoadImmIndex<int32_t>(MachineType::Int32());
+  RunLoadImmIndex<uint32_t>(MachineType::Uint32());
+  RunLoadImmIndex<int32_t*>(MachineType::AnyTagged());
 
   // TODO(titzer): test kRepBit loads
-  // TODO(titzer): test kMachFloat64 loads
+  // TODO(titzer): test MachineType::Float64() loads
   // TODO(titzer): test various indexing modes.
 }
 
@@ -2876,10 +3587,10 @@
     RawMachineAssemblerTester<int32_t> m;
     int32_t OK = 0x29000 + x;
     Node* base = m.PointerConstant(buffer);
-    Node* index0 = m.Int32Constant(x * sizeof(buffer[0]));
+    Node* index0 = m.IntPtrConstant(x * sizeof(buffer[0]));
     Node* load = m.Load(rep, base, index0);
-    Node* index1 = m.Int32Constant(y * sizeof(buffer[0]));
-    m.Store(rep, base, index1, load);
+    Node* index1 = m.IntPtrConstant(y * sizeof(buffer[0]));
+    m.Store(rep.representation(), base, index1, load, kNoWriteBarrier);
     m.Return(m.Int32Constant(OK));
 
     CHECK(buffer[x] != buffer[y]);
@@ -2890,50 +3601,154 @@
 
 
 TEST(RunLoadStore) {
-  RunLoadStore<int8_t>(kMachInt8);
-  RunLoadStore<uint8_t>(kMachUint8);
-  RunLoadStore<int16_t>(kMachInt16);
-  RunLoadStore<uint16_t>(kMachUint16);
-  RunLoadStore<int32_t>(kMachInt32);
-  RunLoadStore<uint32_t>(kMachUint32);
-  RunLoadStore<void*>(kMachAnyTagged);
-  RunLoadStore<float>(kMachFloat32);
-  RunLoadStore<double>(kMachFloat64);
+  RunLoadStore<int8_t>(MachineType::Int8());
+  RunLoadStore<uint8_t>(MachineType::Uint8());
+  RunLoadStore<int16_t>(MachineType::Int16());
+  RunLoadStore<uint16_t>(MachineType::Uint16());
+  RunLoadStore<int32_t>(MachineType::Int32());
+  RunLoadStore<uint32_t>(MachineType::Uint32());
+  RunLoadStore<void*>(MachineType::AnyTagged());
+  RunLoadStore<float>(MachineType::Float32());
+  RunLoadStore<double>(MachineType::Float64());
 }
 
 
-TEST(RunFloat64Binop) {
+TEST(RunFloat32Add) {
+  BufferedRawMachineAssemblerTester<float> m(MachineType::Float32(),
+                                             MachineType::Float32());
+  m.Return(m.Float32Add(m.Parameter(0), m.Parameter(1)));
+
+  FOR_FLOAT32_INPUTS(i) {
+    FOR_FLOAT32_INPUTS(j) {
+      volatile float expected = *i + *j;
+      CheckFloatEq(expected, m.Call(*i, *j));
+    }
+  }
+}
+
+
+TEST(RunFloat32Sub) {
+  BufferedRawMachineAssemblerTester<float> m(MachineType::Float32(),
+                                             MachineType::Float32());
+  m.Return(m.Float32Sub(m.Parameter(0), m.Parameter(1)));
+
+  FOR_FLOAT32_INPUTS(i) {
+    FOR_FLOAT32_INPUTS(j) {
+      volatile float expected = *i - *j;
+      CheckFloatEq(expected, m.Call(*i, *j));
+    }
+  }
+}
+
+
+TEST(RunFloat32Mul) {
+  BufferedRawMachineAssemblerTester<float> m(MachineType::Float32(),
+                                             MachineType::Float32());
+  m.Return(m.Float32Mul(m.Parameter(0), m.Parameter(1)));
+
+  FOR_FLOAT32_INPUTS(i) {
+    FOR_FLOAT32_INPUTS(j) {
+      volatile float expected = *i * *j;
+      CheckFloatEq(expected, m.Call(*i, *j));
+    }
+  }
+}
+
+
+TEST(RunFloat32Div) {
+  BufferedRawMachineAssemblerTester<float> m(MachineType::Float32(),
+                                             MachineType::Float32());
+  m.Return(m.Float32Div(m.Parameter(0), m.Parameter(1)));
+
+  FOR_FLOAT32_INPUTS(i) {
+    FOR_FLOAT32_INPUTS(j) {
+      volatile float expected = *i / *j;
+      CheckFloatEq(expected, m.Call(*i, *j));
+    }
+  }
+}
+
+
+TEST(RunFloat64Add) {
+  BufferedRawMachineAssemblerTester<double> m(MachineType::Float64(),
+                                              MachineType::Float64());
+  m.Return(m.Float64Add(m.Parameter(0), m.Parameter(1)));
+
+  FOR_FLOAT64_INPUTS(i) {
+    FOR_FLOAT64_INPUTS(j) {
+      volatile double expected = *i + *j;
+      CheckDoubleEq(expected, m.Call(*i, *j));
+    }
+  }
+}
+
+
+TEST(RunFloat64Sub) {
+  BufferedRawMachineAssemblerTester<double> m(MachineType::Float64(),
+                                              MachineType::Float64());
+  m.Return(m.Float64Sub(m.Parameter(0), m.Parameter(1)));
+
+  FOR_FLOAT64_INPUTS(i) {
+    FOR_FLOAT64_INPUTS(j) {
+      volatile double expected = *i - *j;
+      CheckDoubleEq(expected, m.Call(*i, *j));
+    }
+  }
+}
+
+
+TEST(RunFloat64Mul) {
+  BufferedRawMachineAssemblerTester<double> m(MachineType::Float64(),
+                                              MachineType::Float64());
+  m.Return(m.Float64Mul(m.Parameter(0), m.Parameter(1)));
+
+  FOR_FLOAT64_INPUTS(i) {
+    FOR_FLOAT64_INPUTS(j) {
+      volatile double expected = *i * *j;
+      CheckDoubleEq(expected, m.Call(*i, *j));
+    }
+  }
+}
+
+
+TEST(RunFloat64Div) {
+  BufferedRawMachineAssemblerTester<double> m(MachineType::Float64(),
+                                              MachineType::Float64());
+  m.Return(m.Float64Div(m.Parameter(0), m.Parameter(1)));
+
+  FOR_FLOAT64_INPUTS(i) {
+    FOR_FLOAT64_INPUTS(j) {
+      volatile double expected = *i / *j;
+      CheckDoubleEq(expected, m.Call(*i, *j));
+    }
+  }
+}
+
+
+TEST(RunFloat64Mod) {
+  BufferedRawMachineAssemblerTester<double> m(MachineType::Float64(),
+                                              MachineType::Float64());
+  m.Return(m.Float64Mod(m.Parameter(0), m.Parameter(1)));
+
+  FOR_FLOAT64_INPUTS(i) {
+    FOR_FLOAT64_INPUTS(j) { CheckDoubleEq(modulo(*i, *j), m.Call(*i, *j)); }
+  }
+}
+
+
+TEST(RunDeadFloat32Binops) {
   RawMachineAssemblerTester<int32_t> m;
-  double result;
 
-  const Operator* ops[] = {m.machine()->Float64Add(), m.machine()->Float64Sub(),
-                           m.machine()->Float64Mul(), m.machine()->Float64Div(),
-                           m.machine()->Float64Mod(), NULL};
-
-  double inf = V8_INFINITY;
-  const Operator* inputs[] = {
-      m.common()->Float64Constant(0),     m.common()->Float64Constant(1),
-      m.common()->Float64Constant(1),     m.common()->Float64Constant(0),
-      m.common()->Float64Constant(0),     m.common()->Float64Constant(-1),
-      m.common()->Float64Constant(-1),    m.common()->Float64Constant(0),
-      m.common()->Float64Constant(0.22),  m.common()->Float64Constant(-1.22),
-      m.common()->Float64Constant(-1.22), m.common()->Float64Constant(0.22),
-      m.common()->Float64Constant(inf),   m.common()->Float64Constant(0.22),
-      m.common()->Float64Constant(inf),   m.common()->Float64Constant(-inf),
-      NULL};
+  const Operator* ops[] = {m.machine()->Float32Add(), m.machine()->Float32Sub(),
+                           m.machine()->Float32Mul(), m.machine()->Float32Div(),
+                           NULL};
 
   for (int i = 0; ops[i] != NULL; i++) {
-    for (int j = 0; inputs[j] != NULL; j += 2) {
-      RawMachineAssemblerTester<int32_t> m;
-      Node* a = m.NewNode(inputs[j]);
-      Node* b = m.NewNode(inputs[j + 1]);
-      Node* binop = m.NewNode(ops[i], a, b);
-      Node* base = m.PointerConstant(&result);
-      Node* zero = m.Int32Constant(0);
-      m.Store(kMachFloat64, base, zero, binop);
-      m.Return(m.Int32Constant(i + j));
-      CHECK_EQ(i + j, m.Call());
-    }
+    RawMachineAssemblerTester<int32_t> m;
+    int constant = 0x53355 + i;
+    m.AddNode(ops[i], m.Float32Constant(0.1f), m.Float32Constant(1.11f));
+    m.Return(m.Int32Constant(constant));
+    CHECK_EQ(constant, m.Call());
   }
 }
 
@@ -2948,13 +3763,28 @@
   for (int i = 0; ops[i] != NULL; i++) {
     RawMachineAssemblerTester<int32_t> m;
     int constant = 0x53355 + i;
-    m.NewNode(ops[i], m.Float64Constant(0.1), m.Float64Constant(1.11));
+    m.AddNode(ops[i], m.Float64Constant(0.1), m.Float64Constant(1.11));
     m.Return(m.Int32Constant(constant));
     CHECK_EQ(constant, m.Call());
   }
 }
 
 
+TEST(RunFloat32AddP) {
+  RawMachineAssemblerTester<int32_t> m;
+  Float32BinopTester bt(&m);
+
+  bt.AddReturn(m.Float32Add(bt.param0, bt.param1));
+
+  FOR_FLOAT32_INPUTS(pl) {
+    FOR_FLOAT32_INPUTS(pr) {
+      float expected = *pl + *pr;
+      CheckFloatEq(expected, bt.call(*pl, *pr));
+    }
+  }
+}
+
+
 TEST(RunFloat64AddP) {
   RawMachineAssemblerTester<int32_t> m;
   Float64BinopTester bt(&m);
@@ -2964,12 +3794,137 @@
   FOR_FLOAT64_INPUTS(pl) {
     FOR_FLOAT64_INPUTS(pr) {
       double expected = *pl + *pr;
-      CHECK_EQ(expected, bt.call(*pl, *pr));
+      CheckDoubleEq(expected, bt.call(*pl, *pr));
     }
   }
 }
 
 
+TEST(RunFloa32MaxP) {
+  RawMachineAssemblerTester<int32_t> m;
+  Float32BinopTester bt(&m);
+  if (!m.machine()->Float32Max().IsSupported()) return;
+
+  bt.AddReturn(m.Float32Max(bt.param0, bt.param1));
+
+  FOR_FLOAT32_INPUTS(pl) {
+    FOR_FLOAT32_INPUTS(pr) {
+      double expected = *pl > *pr ? *pl : *pr;
+      CheckDoubleEq(expected, bt.call(*pl, *pr));
+    }
+  }
+}
+
+
+TEST(RunFloat64MaxP) {
+  RawMachineAssemblerTester<int32_t> m;
+  Float64BinopTester bt(&m);
+  if (!m.machine()->Float64Max().IsSupported()) return;
+
+  bt.AddReturn(m.Float64Max(bt.param0, bt.param1));
+
+  FOR_FLOAT64_INPUTS(pl) {
+    FOR_FLOAT64_INPUTS(pr) {
+      double expected = *pl > *pr ? *pl : *pr;
+      CheckDoubleEq(expected, bt.call(*pl, *pr));
+    }
+  }
+}
+
+
+TEST(RunFloat32MinP) {
+  RawMachineAssemblerTester<int32_t> m;
+  Float32BinopTester bt(&m);
+  if (!m.machine()->Float32Min().IsSupported()) return;
+
+  bt.AddReturn(m.Float32Min(bt.param0, bt.param1));
+
+  FOR_FLOAT32_INPUTS(pl) {
+    FOR_FLOAT32_INPUTS(pr) {
+      double expected = *pl < *pr ? *pl : *pr;
+      CheckDoubleEq(expected, bt.call(*pl, *pr));
+    }
+  }
+}
+
+
+TEST(RunFloat64MinP) {
+  RawMachineAssemblerTester<int32_t> m;
+  Float64BinopTester bt(&m);
+  if (!m.machine()->Float64Min().IsSupported()) return;
+
+  bt.AddReturn(m.Float64Min(bt.param0, bt.param1));
+
+  FOR_FLOAT64_INPUTS(pl) {
+    FOR_FLOAT64_INPUTS(pr) {
+      double expected = *pl < *pr ? *pl : *pr;
+      CheckDoubleEq(expected, bt.call(*pl, *pr));
+    }
+  }
+}
+
+
+TEST(RunFloat32SubP) {
+  RawMachineAssemblerTester<int32_t> m;
+  Float32BinopTester bt(&m);
+
+  bt.AddReturn(m.Float32Sub(bt.param0, bt.param1));
+
+  FOR_FLOAT32_INPUTS(pl) {
+    FOR_FLOAT32_INPUTS(pr) {
+      float expected = *pl - *pr;
+      CheckFloatEq(expected, bt.call(*pl, *pr));
+    }
+  }
+}
+
+
+TEST(RunFloat32SubImm1) {
+  FOR_FLOAT32_INPUTS(i) {
+    BufferedRawMachineAssemblerTester<float> m(MachineType::Float32());
+    m.Return(m.Float32Sub(m.Float32Constant(*i), m.Parameter(0)));
+
+    FOR_FLOAT32_INPUTS(j) {
+      volatile float expected = *i - *j;
+      CheckFloatEq(expected, m.Call(*j));
+    }
+  }
+}
+
+
+TEST(RunFloat32SubImm2) {
+  FOR_FLOAT32_INPUTS(i) {
+    BufferedRawMachineAssemblerTester<float> m(MachineType::Float32());
+    m.Return(m.Float32Sub(m.Parameter(0), m.Float32Constant(*i)));
+
+    FOR_FLOAT32_INPUTS(j) {
+      volatile float expected = *j - *i;
+      CheckFloatEq(expected, m.Call(*j));
+    }
+  }
+}
+
+
+TEST(RunFloat64SubImm1) {
+  FOR_FLOAT64_INPUTS(i) {
+    BufferedRawMachineAssemblerTester<double> m(MachineType::Float64());
+    m.Return(m.Float64Sub(m.Float64Constant(*i), m.Parameter(0)));
+
+    FOR_FLOAT64_INPUTS(j) { CheckFloatEq(*i - *j, m.Call(*j)); }
+  }
+}
+
+
+TEST(RunFloat64SubImm2) {
+  FOR_FLOAT64_INPUTS(i) {
+    BufferedRawMachineAssemblerTester<double> m(MachineType::Float64());
+    m.Return(m.Float64Sub(m.Parameter(0), m.Float64Constant(*i)));
+
+    FOR_FLOAT64_INPUTS(j) { CheckFloatEq(*j - *i, m.Call(*j)); }
+  }
+}
+
+
 TEST(RunFloat64SubP) {
   RawMachineAssemblerTester<int32_t> m;
   Float64BinopTester bt(&m);
@@ -2979,47 +3934,22 @@
   FOR_FLOAT64_INPUTS(pl) {
     FOR_FLOAT64_INPUTS(pr) {
       double expected = *pl - *pr;
-      CHECK_EQ(expected, bt.call(*pl, *pr));
+      CheckDoubleEq(expected, bt.call(*pl, *pr));
     }
   }
 }
 
 
-TEST(RunFloat64SubImm1) {
-  double input = 0.0;
-  double output = 0.0;
+TEST(RunFloat32MulP) {
+  RawMachineAssemblerTester<int32_t> m;
+  Float32BinopTester bt(&m);
 
-  FOR_FLOAT64_INPUTS(i) {
-    RawMachineAssemblerTester<int32_t> m;
-    Node* t0 = m.LoadFromPointer(&input, kMachFloat64);
-    Node* t1 = m.Float64Sub(m.Float64Constant(*i), t0);
-    m.StoreToPointer(&output, kMachFloat64, t1);
-    m.Return(m.Int32Constant(0));
-    FOR_FLOAT64_INPUTS(j) {
-      input = *j;
-      double expected = *i - input;
-      CHECK_EQ(0, m.Call());
-      CHECK_EQ(expected, output);
-    }
-  }
-}
+  bt.AddReturn(m.Float32Mul(bt.param0, bt.param1));
 
-
-TEST(RunFloat64SubImm2) {
-  double input = 0.0;
-  double output = 0.0;
-
-  FOR_FLOAT64_INPUTS(i) {
-    RawMachineAssemblerTester<int32_t> m;
-    Node* t0 = m.LoadFromPointer(&input, kMachFloat64);
-    Node* t1 = m.Float64Sub(t0, m.Float64Constant(*i));
-    m.StoreToPointer(&output, kMachFloat64, t1);
-    m.Return(m.Int32Constant(0));
-    FOR_FLOAT64_INPUTS(j) {
-      input = *j;
-      double expected = input - *i;
-      CHECK_EQ(0, m.Call());
-      CHECK_EQ(expected, output);
+  FOR_FLOAT32_INPUTS(pl) {
+    FOR_FLOAT32_INPUTS(pr) {
+      float expected = *pl * *pr;
+      CheckFloatEq(expected, bt.call(*pl, *pr));
     }
   }
 }
@@ -3034,131 +3964,111 @@
   FOR_FLOAT64_INPUTS(pl) {
     FOR_FLOAT64_INPUTS(pr) {
       double expected = *pl * *pr;
-      CHECK_EQ(expected, bt.call(*pl, *pr));
+      CheckDoubleEq(expected, bt.call(*pl, *pr));
     }
   }
 }
 
 
-TEST(RunFloat64MulAndFloat64AddP) {
-  double input_a = 0.0;
-  double input_b = 0.0;
-  double input_c = 0.0;
-  double output = 0.0;
-
-  {
-    RawMachineAssemblerTester<int32_t> m;
-    Node* a = m.LoadFromPointer(&input_a, kMachFloat64);
-    Node* b = m.LoadFromPointer(&input_b, kMachFloat64);
-    Node* c = m.LoadFromPointer(&input_c, kMachFloat64);
-    m.StoreToPointer(&output, kMachFloat64,
-                     m.Float64Add(m.Float64Mul(a, b), c));
-    m.Return(m.Int32Constant(0));
-    FOR_FLOAT64_INPUTS(i) {
-      FOR_FLOAT64_INPUTS(j) {
-        FOR_FLOAT64_INPUTS(k) {
-          input_a = *i;
-          input_b = *j;
-          input_c = *k;
-          volatile double temp = input_a * input_b;
-          volatile double expected = temp + input_c;
-          CHECK_EQ(0, m.Call());
-          CHECK_EQ(expected, output);
-        }
-      }
-    }
-  }
-  {
-    RawMachineAssemblerTester<int32_t> m;
-    Node* a = m.LoadFromPointer(&input_a, kMachFloat64);
-    Node* b = m.LoadFromPointer(&input_b, kMachFloat64);
-    Node* c = m.LoadFromPointer(&input_c, kMachFloat64);
-    m.StoreToPointer(&output, kMachFloat64,
-                     m.Float64Add(a, m.Float64Mul(b, c)));
-    m.Return(m.Int32Constant(0));
-    FOR_FLOAT64_INPUTS(i) {
-      FOR_FLOAT64_INPUTS(j) {
-        FOR_FLOAT64_INPUTS(k) {
-          input_a = *i;
-          input_b = *j;
-          input_c = *k;
-          volatile double temp = input_b * input_c;
-          volatile double expected = input_a + temp;
-          CHECK_EQ(0, m.Call());
-          CHECK_EQ(expected, output);
-        }
-      }
-    }
-  }
-}
-
-
-TEST(RunFloat64MulAndFloat64SubP) {
-  double input_a = 0.0;
-  double input_b = 0.0;
-  double input_c = 0.0;
-  double output = 0.0;
-
-  RawMachineAssemblerTester<int32_t> m;
-  Node* a = m.LoadFromPointer(&input_a, kMachFloat64);
-  Node* b = m.LoadFromPointer(&input_b, kMachFloat64);
-  Node* c = m.LoadFromPointer(&input_c, kMachFloat64);
-  m.StoreToPointer(&output, kMachFloat64, m.Float64Sub(a, m.Float64Mul(b, c)));
-  m.Return(m.Int32Constant(0));
+TEST(RunFloat64MulAndFloat64Add1) {
+  BufferedRawMachineAssemblerTester<double> m(
+      MachineType::Float64(), MachineType::Float64(), MachineType::Float64());
+  m.Return(m.Float64Add(m.Float64Mul(m.Parameter(0), m.Parameter(1)),
+                        m.Parameter(2)));
 
   FOR_FLOAT64_INPUTS(i) {
     FOR_FLOAT64_INPUTS(j) {
       FOR_FLOAT64_INPUTS(k) {
-        input_a = *i;
-        input_b = *j;
-        input_c = *k;
-        volatile double temp = input_b * input_c;
-        volatile double expected = input_a - temp;
-        CHECK_EQ(0, m.Call());
-        CHECK_EQ(expected, output);
+        CheckDoubleEq((*i * *j) + *k, m.Call(*i, *j, *k));
       }
     }
   }
 }
 
 
-TEST(RunFloat64MulImm) {
-  double input = 0.0;
-  double output = 0.0;
+TEST(RunFloat64MulAndFloat64Add2) {
+  BufferedRawMachineAssemblerTester<double> m(
+      MachineType::Float64(), MachineType::Float64(), MachineType::Float64());
+  m.Return(m.Float64Add(m.Parameter(0),
+                        m.Float64Mul(m.Parameter(1), m.Parameter(2))));
 
-  {
-    FOR_FLOAT64_INPUTS(i) {
-      RawMachineAssemblerTester<int32_t> m;
-      Node* t0 = m.LoadFromPointer(&input, kMachFloat64);
-      Node* t1 = m.Float64Mul(m.Float64Constant(*i), t0);
-      m.StoreToPointer(&output, kMachFloat64, t1);
-      m.Return(m.Int32Constant(0));
-      FOR_FLOAT64_INPUTS(j) {
-        input = *j;
-        double expected = *i * input;
-        CHECK_EQ(0, m.Call());
-        CHECK_EQ(expected, output);
+  FOR_FLOAT64_INPUTS(i) {
+    FOR_FLOAT64_INPUTS(j) {
+      FOR_FLOAT64_INPUTS(k) {
+        CheckDoubleEq(*i + (*j * *k), m.Call(*i, *j, *k));
       }
     }
   }
-  {
-    FOR_FLOAT64_INPUTS(i) {
-      RawMachineAssemblerTester<int32_t> m;
-      Node* t0 = m.LoadFromPointer(&input, kMachFloat64);
-      Node* t1 = m.Float64Mul(t0, m.Float64Constant(*i));
-      m.StoreToPointer(&output, kMachFloat64, t1);
-      m.Return(m.Int32Constant(0));
-      FOR_FLOAT64_INPUTS(j) {
-        input = *j;
-        double expected = input * *i;
-        CHECK_EQ(0, m.Call());
-        CHECK_EQ(expected, output);
+}
+
+
+TEST(RunFloat64MulAndFloat64Sub1) {
+  BufferedRawMachineAssemblerTester<double> m(
+      MachineType::Float64(), MachineType::Float64(), MachineType::Float64());
+  m.Return(m.Float64Sub(m.Float64Mul(m.Parameter(0), m.Parameter(1)),
+                        m.Parameter(2)));
+
+  FOR_FLOAT64_INPUTS(i) {
+    FOR_FLOAT64_INPUTS(j) {
+      FOR_FLOAT64_INPUTS(k) {
+        CheckDoubleEq((*i * *j) - *k, m.Call(*i, *j, *k));
       }
     }
   }
 }
 
 
+TEST(RunFloat64MulAndFloat64Sub2) {
+  BufferedRawMachineAssemblerTester<double> m(
+      MachineType::Float64(), MachineType::Float64(), MachineType::Float64());
+  m.Return(m.Float64Sub(m.Parameter(0),
+                        m.Float64Mul(m.Parameter(1), m.Parameter(2))));
+
+  FOR_FLOAT64_INPUTS(i) {
+    FOR_FLOAT64_INPUTS(j) {
+      FOR_FLOAT64_INPUTS(k) {
+        CheckDoubleEq(*i - (*j * *k), m.Call(*i, *j, *k));
+      }
+    }
+  }
+}
+
+
+TEST(RunFloat64MulImm1) {
+  FOR_FLOAT64_INPUTS(i) {
+    BufferedRawMachineAssemblerTester<double> m(MachineType::Float64());
+    m.Return(m.Float64Mul(m.Float64Constant(*i), m.Parameter(0)));
+
+    FOR_FLOAT64_INPUTS(j) { CheckFloatEq(*i * *j, m.Call(*j)); }
+  }
+}
+
+
+TEST(RunFloat64MulImm2) {
+  FOR_FLOAT64_INPUTS(i) {
+    BufferedRawMachineAssemblerTester<double> m(MachineType::Float64());
+    m.Return(m.Float64Mul(m.Parameter(0), m.Float64Constant(*i)));
+
+    FOR_FLOAT64_INPUTS(j) { CheckFloatEq(*j * *i, m.Call(*j)); }
+  }
+}
+
+
+TEST(RunFloat32DivP) {
+  RawMachineAssemblerTester<int32_t> m;
+  Float32BinopTester bt(&m);
+
+  bt.AddReturn(m.Float32Div(bt.param0, bt.param1));
+
+  FOR_FLOAT32_INPUTS(pl) {
+    FOR_FLOAT32_INPUTS(pr) {
+      float expected = *pl / *pr;
+      CheckFloatEq(expected, bt.call(*pl, *pr));
+    }
+  }
+}
+
+
 TEST(RunFloat64DivP) {
   RawMachineAssemblerTester<int32_t> m;
   Float64BinopTester bt(&m);
@@ -3168,7 +4078,7 @@
   FOR_FLOAT64_INPUTS(pl) {
     FOR_FLOAT64_INPUTS(pr) {
       double expected = *pl / *pr;
-      CHECK_EQ(expected, bt.call(*pl, *pr));
+      CheckDoubleEq(expected, bt.call(*pl, *pr));
     }
   }
 }
@@ -3184,292 +4094,87 @@
     FOR_FLOAT64_INPUTS(j) {
       double expected = modulo(*i, *j);
       double found = bt.call(*i, *j);
-      CHECK_EQ(expected, found);
+      CheckDoubleEq(expected, found);
     }
   }
 }
 
 
 TEST(RunChangeInt32ToFloat64_A) {
-  RawMachineAssemblerTester<int32_t> m;
   int32_t magic = 0x986234;
-  double result = 0;
-
-  Node* convert = m.ChangeInt32ToFloat64(m.Int32Constant(magic));
-  m.Store(kMachFloat64, m.PointerConstant(&result), m.Int32Constant(0),
-          convert);
-  m.Return(m.Int32Constant(magic));
-
-  CHECK_EQ(magic, m.Call());
-  CHECK_EQ(static_cast<double>(magic), result);
+  BufferedRawMachineAssemblerTester<double> m;
+  m.Return(m.ChangeInt32ToFloat64(m.Int32Constant(magic)));
+  CheckDoubleEq(static_cast<double>(magic), m.Call());
 }
 
 
 TEST(RunChangeInt32ToFloat64_B) {
-  RawMachineAssemblerTester<int32_t> m(kMachInt32);
-  double output = 0;
+  BufferedRawMachineAssemblerTester<double> m(MachineType::Int32());
+  m.Return(m.ChangeInt32ToFloat64(m.Parameter(0)));
 
-  Node* convert = m.ChangeInt32ToFloat64(m.Parameter(0));
-  m.Store(kMachFloat64, m.PointerConstant(&output), m.Int32Constant(0),
-          convert);
-  m.Return(m.Parameter(0));
-
-  FOR_INT32_INPUTS(i) {
-    int32_t expect = *i;
-    CHECK_EQ(expect, m.Call(expect));
-    CHECK_EQ(static_cast<double>(expect), output);
-  }
+  FOR_INT32_INPUTS(i) { CheckDoubleEq(static_cast<double>(*i), m.Call(*i)); }
 }
 
 
-TEST(RunChangeUint32ToFloat64_B) {
-  RawMachineAssemblerTester<int32_t> m(kMachUint32);
-  double output = 0;
+TEST(RunChangeUint32ToFloat64) {
+  BufferedRawMachineAssemblerTester<double> m(MachineType::Uint32());
+  m.Return(m.ChangeUint32ToFloat64(m.Parameter(0)));
 
-  Node* convert = m.ChangeUint32ToFloat64(m.Parameter(0));
-  m.Store(kMachFloat64, m.PointerConstant(&output), m.Int32Constant(0),
-          convert);
-  m.Return(m.Parameter(0));
-
-  FOR_UINT32_INPUTS(i) {
-    uint32_t expect = *i;
-    CHECK_EQ(expect, m.Call(expect));
-    CHECK_EQ(static_cast<double>(expect), output);
-  }
-}
-
-
-TEST(RunChangeUint32ToFloat64_spilled) {
-  RawMachineAssemblerTester<int32_t> m;
-  const int kNumInputs = 32;
-  int32_t magic = 0x786234;
-  uint32_t input[kNumInputs];
-  double result[kNumInputs];
-  Node* input_node[kNumInputs];
-
-  for (int i = 0; i < kNumInputs; i++) {
-    input_node[i] =
-        m.Load(kMachUint32, m.PointerConstant(&input), m.Int32Constant(i * 4));
-  }
-
-  for (int i = 0; i < kNumInputs; i++) {
-    m.Store(kMachFloat64, m.PointerConstant(&result), m.Int32Constant(i * 8),
-            m.ChangeUint32ToFloat64(input_node[i]));
-  }
-
-  m.Return(m.Int32Constant(magic));
-
-  for (int i = 0; i < kNumInputs; i++) {
-    input[i] = 100 + i;
-  }
-
-  CHECK_EQ(magic, m.Call());
-
-  for (int i = 0; i < kNumInputs; i++) {
-    CHECK_EQ(result[i], static_cast<double>(100 + i));
-  }
+  FOR_UINT32_INPUTS(i) { CheckDoubleEq(static_cast<double>(*i), m.Call(*i)); }
 }
 
 
 TEST(RunChangeFloat64ToInt32_A) {
-  RawMachineAssemblerTester<int32_t> m;
-  int32_t magic = 0x786234;
-  double input = 11.1;
-  int32_t result = 0;
-
-  m.Store(kMachInt32, m.PointerConstant(&result), m.Int32Constant(0),
-          m.ChangeFloat64ToInt32(m.Float64Constant(input)));
-  m.Return(m.Int32Constant(magic));
-
-  CHECK_EQ(magic, m.Call());
-  CHECK_EQ(static_cast<int32_t>(input), result);
+  BufferedRawMachineAssemblerTester<int32_t> m;
+  double magic = 11.1;
+  m.Return(m.ChangeFloat64ToInt32(m.Float64Constant(magic)));
+  CHECK_EQ(static_cast<int32_t>(magic), m.Call());
 }
 
 
 TEST(RunChangeFloat64ToInt32_B) {
-  RawMachineAssemblerTester<int32_t> m;
-  double input = 0;
-  int32_t output = 0;
+  BufferedRawMachineAssemblerTester<int32_t> m(MachineType::Float64());
+  m.Return(m.ChangeFloat64ToInt32(m.Parameter(0)));
 
-  Node* load =
-      m.Load(kMachFloat64, m.PointerConstant(&input), m.Int32Constant(0));
-  Node* convert = m.ChangeFloat64ToInt32(load);
-  m.Store(kMachInt32, m.PointerConstant(&output), m.Int32Constant(0), convert);
-  m.Return(convert);
+  // Note we don't check fractional inputs, or inputs outside the range of
+  // int32, because these Convert operators really should be Change operators.
+  FOR_INT32_INPUTS(i) { CHECK_EQ(*i, m.Call(static_cast<double>(*i))); }
+
+  for (int32_t n = 1; n < 31; ++n) {
+    CHECK_EQ(1 << n, m.Call(static_cast<double>(1 << n)));
+  }
+
+  for (int32_t n = 1; n < 31; ++n) {
+    CHECK_EQ(3 << n, m.Call(static_cast<double>(3 << n)));
+  }
+}
+
+
+TEST(RunChangeFloat64ToUint32) {
+  BufferedRawMachineAssemblerTester<uint32_t> m(MachineType::Float64());
+  m.Return(m.ChangeFloat64ToUint32(m.Parameter(0)));
 
   {
-    FOR_INT32_INPUTS(i) {
-      input = *i;
-      int32_t expect = *i;
-      CHECK_EQ(expect, m.Call());
-      CHECK_EQ(expect, output);
-    }
+    FOR_UINT32_INPUTS(i) { CHECK_EQ(*i, m.Call(static_cast<double>(*i))); }
   }
 
   // Check various powers of 2.
   for (int32_t n = 1; n < 31; ++n) {
-    {
-      input = 1 << n;
-      int32_t expect = static_cast<int32_t>(input);
-      CHECK_EQ(expect, m.Call());
-      CHECK_EQ(expect, output);
-    }
+    { CHECK_EQ(1u << n, m.Call(static_cast<double>(1u << n))); }
 
-    {
-      input = 3 << n;
-      int32_t expect = static_cast<int32_t>(input);
-      CHECK_EQ(expect, m.Call());
-      CHECK_EQ(expect, output);
-    }
+    { CHECK_EQ(3u << n, m.Call(static_cast<double>(3u << n))); }
   }
   // Note we don't check fractional inputs, because these Convert operators
   // really should be Change operators.
 }
 
 
-TEST(RunChangeFloat64ToUint32_B) {
-  RawMachineAssemblerTester<int32_t> m;
-  double input = 0;
-  int32_t output = 0;
+TEST(RunTruncateFloat64ToFloat32) {
+  BufferedRawMachineAssemblerTester<float> m(MachineType::Float64());
 
-  Node* load =
-      m.Load(kMachFloat64, m.PointerConstant(&input), m.Int32Constant(0));
-  Node* convert = m.ChangeFloat64ToUint32(load);
-  m.Store(kMachInt32, m.PointerConstant(&output), m.Int32Constant(0), convert);
-  m.Return(convert);
+  m.Return(m.TruncateFloat64ToFloat32(m.Parameter(0)));
 
-  {
-    FOR_UINT32_INPUTS(i) {
-      input = *i;
-      // TODO(titzer): add a CheckEqualsHelper overload for uint32_t.
-      int32_t expect = static_cast<int32_t>(*i);
-      CHECK_EQ(expect, m.Call());
-      CHECK_EQ(expect, output);
-    }
-  }
-
-  // Check various powers of 2.
-  for (int32_t n = 1; n < 31; ++n) {
-    {
-      input = 1u << n;
-      int32_t expect = static_cast<int32_t>(static_cast<uint32_t>(input));
-      CHECK_EQ(expect, m.Call());
-      CHECK_EQ(expect, output);
-    }
-
-    {
-      input = 3u << n;
-      int32_t expect = static_cast<int32_t>(static_cast<uint32_t>(input));
-      CHECK_EQ(expect, m.Call());
-      CHECK_EQ(expect, output);
-    }
-  }
-  // Note we don't check fractional inputs, because these Convert operators
-  // really should be Change operators.
-}
-
-
-TEST(RunChangeFloat64ToInt32_spilled) {
-  RawMachineAssemblerTester<int32_t> m;
-  const int kNumInputs = 32;
-  int32_t magic = 0x786234;
-  double input[kNumInputs];
-  int32_t result[kNumInputs];
-  Node* input_node[kNumInputs];
-
-  for (int i = 0; i < kNumInputs; i++) {
-    input_node[i] =
-        m.Load(kMachFloat64, m.PointerConstant(&input), m.Int32Constant(i * 8));
-  }
-
-  for (int i = 0; i < kNumInputs; i++) {
-    m.Store(kMachInt32, m.PointerConstant(&result), m.Int32Constant(i * 4),
-            m.ChangeFloat64ToInt32(input_node[i]));
-  }
-
-  m.Return(m.Int32Constant(magic));
-
-  for (int i = 0; i < kNumInputs; i++) {
-    input[i] = 100.9 + i;
-  }
-
-  CHECK_EQ(magic, m.Call());
-
-  for (int i = 0; i < kNumInputs; i++) {
-    CHECK_EQ(result[i], 100 + i);
-  }
-}
-
-
-TEST(RunChangeFloat64ToUint32_spilled) {
-  RawMachineAssemblerTester<uint32_t> m;
-  const int kNumInputs = 32;
-  int32_t magic = 0x786234;
-  double input[kNumInputs];
-  uint32_t result[kNumInputs];
-  Node* input_node[kNumInputs];
-
-  for (int i = 0; i < kNumInputs; i++) {
-    input_node[i] =
-        m.Load(kMachFloat64, m.PointerConstant(&input), m.Int32Constant(i * 8));
-  }
-
-  for (int i = 0; i < kNumInputs; i++) {
-    m.Store(kMachUint32, m.PointerConstant(&result), m.Int32Constant(i * 4),
-            m.ChangeFloat64ToUint32(input_node[i]));
-  }
-
-  m.Return(m.Int32Constant(magic));
-
-  for (int i = 0; i < kNumInputs; i++) {
-    if (i % 2) {
-      input[i] = 100 + i + 2147483648u;
-    } else {
-      input[i] = 100 + i;
-    }
-  }
-
-  CHECK_EQ(magic, m.Call());
-
-  for (int i = 0; i < kNumInputs; i++) {
-    if (i % 2) {
-      CHECK_UINT32_EQ(result[i], static_cast<uint32_t>(100 + i + 2147483648u));
-    } else {
-      CHECK_UINT32_EQ(result[i], static_cast<uint32_t>(100 + i));
-    }
-  }
-}
-
-
-TEST(RunTruncateFloat64ToFloat32_spilled) {
-  RawMachineAssemblerTester<uint32_t> m;
-  const int kNumInputs = 32;
-  int32_t magic = 0x786234;
-  double input[kNumInputs];
-  float result[kNumInputs];
-  Node* input_node[kNumInputs];
-
-  for (int i = 0; i < kNumInputs; i++) {
-    input_node[i] =
-        m.Load(kMachFloat64, m.PointerConstant(&input), m.Int32Constant(i * 8));
-  }
-
-  for (int i = 0; i < kNumInputs; i++) {
-    m.Store(kMachFloat32, m.PointerConstant(&result), m.Int32Constant(i * 4),
-            m.TruncateFloat64ToFloat32(input_node[i]));
-  }
-
-  m.Return(m.Int32Constant(magic));
-
-  for (int i = 0; i < kNumInputs; i++) {
-    input[i] = 0.1 + i;
-  }
-
-  CHECK_EQ(magic, m.Call());
-
-  for (int i = 0; i < kNumInputs; i++) {
-    CHECK_EQ(result[i], DoubleToFloat32(input[i]));
-  }
+  FOR_FLOAT64_INPUTS(i) { CheckFloatEq(DoubleToFloat32(*i), m.Call(*i)); }
 }
 
 
@@ -3497,11 +4202,11 @@
   int false_val = 0x10777;
 
   // x = false_val; while(false) { x++; } return x;
-  MLabel header, body, end;
+  RawMachineLabel header, body, end;
   Node* false_node = m.Int32Constant(false_val);
   m.Goto(&header);
   m.Bind(&header);
-  Node* phi = m.Phi(kMachInt32, false_node, false_node);
+  Node* phi = m.Phi(MachineRepresentation::kWord32, false_node, false_node);
   m.Branch(m.Int32Constant(0), &body, &end);
   m.Bind(&body);
   Node* add = m.Int32Add(phi, m.Int32Constant(1));
@@ -3514,6 +4219,32 @@
 }
 
 
+TEST(RunFloatDiamond) {
+  RawMachineAssemblerTester<int32_t> m;
+
+  const int magic = 99645;
+  float buffer = 0.1f;
+  float constant = 99.99f;
+
+  RawMachineLabel blocka, blockb, end;
+  Node* k1 = m.Float32Constant(constant);
+  Node* k2 = m.Float32Constant(0 - constant);
+  m.Branch(m.Int32Constant(0), &blocka, &blockb);
+  m.Bind(&blocka);
+  m.Goto(&end);
+  m.Bind(&blockb);
+  m.Goto(&end);
+  m.Bind(&end);
+  Node* phi = m.Phi(MachineRepresentation::kFloat32, k2, k1);
+  m.Store(MachineRepresentation::kFloat32, m.PointerConstant(&buffer),
+          m.IntPtrConstant(0), phi, kNoWriteBarrier);
+  m.Return(m.Int32Constant(magic));
+
+  CHECK_EQ(magic, m.Call());
+  CHECK(constant == buffer);
+}
+
+
 TEST(RunDoubleDiamond) {
   RawMachineAssemblerTester<int32_t> m;
 
@@ -3521,7 +4252,7 @@
   double buffer = 0.1;
   double constant = 99.99;
 
-  MLabel blocka, blockb, end;
+  RawMachineLabel blocka, blockb, end;
   Node* k1 = m.Float64Constant(constant);
   Node* k2 = m.Float64Constant(0 - constant);
   m.Branch(m.Int32Constant(0), &blocka, &blockb);
@@ -3530,8 +4261,9 @@
   m.Bind(&blockb);
   m.Goto(&end);
   m.Bind(&end);
-  Node* phi = m.Phi(kMachFloat64, k2, k1);
-  m.Store(kMachFloat64, m.PointerConstant(&buffer), m.Int32Constant(0), phi);
+  Node* phi = m.Phi(MachineRepresentation::kFloat64, k2, k1);
+  m.Store(MachineRepresentation::kFloat64, m.PointerConstant(&buffer),
+          m.Int32Constant(0), phi, kNoWriteBarrier);
   m.Return(m.Int32Constant(magic));
 
   CHECK_EQ(magic, m.Call());
@@ -3547,7 +4279,7 @@
       CcTest::i_isolate()->factory()->InternalizeUtf8String("A");
   String* buffer;
 
-  MLabel blocka, blockb, end;
+  RawMachineLabel blocka, blockb, end;
   Node* k1 = m.StringConstant("A");
   Node* k2 = m.StringConstant("B");
   m.Branch(m.Int32Constant(0), &blocka, &blockb);
@@ -3556,8 +4288,9 @@
   m.Bind(&blockb);
   m.Goto(&end);
   m.Bind(&end);
-  Node* phi = m.Phi(kMachAnyTagged, k2, k1);
-  m.Store(kMachAnyTagged, m.PointerConstant(&buffer), m.Int32Constant(0), phi);
+  Node* phi = m.Phi(MachineRepresentation::kTagged, k2, k1);
+  m.Store(MachineRepresentation::kTagged, m.PointerConstant(&buffer),
+          m.Int32Constant(0), phi, kNoWriteBarrier);
   m.Return(m.Int32Constant(magic));
 
   CHECK_EQ(magic, m.Call());
@@ -3575,7 +4308,7 @@
       CcTest::i_isolate()->factory()->InternalizeUtf8String("AX");
   String* rbuffer;
 
-  MLabel blocka, blockb, end;
+  RawMachineLabel blocka, blockb, end;
   Node* d1 = m.Float64Constant(dconstant);
   Node* d2 = m.Float64Constant(0 - dconstant);
   Node* r1 = m.StringConstant("AX");
@@ -3586,11 +4319,12 @@
   m.Bind(&blockb);
   m.Goto(&end);
   m.Bind(&end);
-  Node* dphi = m.Phi(kMachFloat64, d2, d1);
-  Node* rphi = m.Phi(kMachAnyTagged, r2, r1);
-  m.Store(kMachFloat64, m.PointerConstant(&dbuffer), m.Int32Constant(0), dphi);
-  m.Store(kMachAnyTagged, m.PointerConstant(&rbuffer), m.Int32Constant(0),
-          rphi);
+  Node* dphi = m.Phi(MachineRepresentation::kFloat64, d2, d1);
+  Node* rphi = m.Phi(MachineRepresentation::kTagged, r2, r1);
+  m.Store(MachineRepresentation::kFloat64, m.PointerConstant(&dbuffer),
+          m.Int32Constant(0), dphi, kNoWriteBarrier);
+  m.Store(MachineRepresentation::kTagged, m.PointerConstant(&rbuffer),
+          m.Int32Constant(0), rphi, kNoWriteBarrier);
   m.Return(m.Int32Constant(magic));
 
   CHECK_EQ(magic, m.Call());
@@ -3609,7 +4343,7 @@
       CcTest::i_isolate()->factory()->InternalizeUtf8String("AD");
   String* rbuffer;
 
-  MLabel blocka, blockb, mid, blockd, blocke, end;
+  RawMachineLabel blocka, blockb, mid, blockd, blocke, end;
   Node* d1 = m.Float64Constant(dconstant);
   Node* d2 = m.Float64Constant(0 - dconstant);
   Node* r1 = m.StringConstant("AD");
@@ -3620,8 +4354,8 @@
   m.Bind(&blockb);
   m.Goto(&mid);
   m.Bind(&mid);
-  Node* dphi1 = m.Phi(kMachFloat64, d2, d1);
-  Node* rphi1 = m.Phi(kMachAnyTagged, r2, r1);
+  Node* dphi1 = m.Phi(MachineRepresentation::kFloat64, d2, d1);
+  Node* rphi1 = m.Phi(MachineRepresentation::kTagged, r2, r1);
   m.Branch(m.Int32Constant(0), &blockd, &blocke);
 
   m.Bind(&blockd);
@@ -3629,12 +4363,13 @@
   m.Bind(&blocke);
   m.Goto(&end);
   m.Bind(&end);
-  Node* dphi2 = m.Phi(kMachFloat64, d1, dphi1);
-  Node* rphi2 = m.Phi(kMachAnyTagged, r1, rphi1);
+  Node* dphi2 = m.Phi(MachineRepresentation::kFloat64, d1, dphi1);
+  Node* rphi2 = m.Phi(MachineRepresentation::kTagged, r1, rphi1);
 
-  m.Store(kMachFloat64, m.PointerConstant(&dbuffer), m.Int32Constant(0), dphi2);
-  m.Store(kMachAnyTagged, m.PointerConstant(&rbuffer), m.Int32Constant(0),
-          rphi2);
+  m.Store(MachineRepresentation::kFloat64, m.PointerConstant(&dbuffer),
+          m.Int32Constant(0), dphi2, kNoWriteBarrier);
+  m.Store(MachineRepresentation::kTagged, m.PointerConstant(&rbuffer),
+          m.Int32Constant(0), rphi2, kNoWriteBarrier);
   m.Return(m.Int32Constant(magic));
 
   CHECK_EQ(magic, m.Call());
@@ -3645,7 +4380,7 @@
 
 TEST(RunDoubleLoopPhi) {
   RawMachineAssemblerTester<int32_t> m;
-  MLabel header, body, end;
+  RawMachineLabel header, body, end;
 
   int magic = 99773;
   double buffer = 0.99;
@@ -3656,13 +4391,14 @@
 
   m.Goto(&header);
   m.Bind(&header);
-  Node* phi = m.Phi(kMachFloat64, dk, dk);
+  Node* phi = m.Phi(MachineRepresentation::kFloat64, dk, dk);
   phi->ReplaceInput(1, phi);
   m.Branch(zero, &body, &end);
   m.Bind(&body);
   m.Goto(&header);
   m.Bind(&end);
-  m.Store(kMachFloat64, m.PointerConstant(&buffer), m.Int32Constant(0), phi);
+  m.Store(MachineRepresentation::kFloat64, m.PointerConstant(&buffer),
+          m.Int32Constant(0), phi, kNoWriteBarrier);
   m.Return(m.Int32Constant(magic));
 
   CHECK_EQ(magic, m.Call());
@@ -3676,13 +4412,13 @@
   Node* ten = m.Int32Constant(10);
   Node* one = m.Int32Constant(1);
 
-  MLabel header, body, body_cont, end;
+  RawMachineLabel header, body, body_cont, end;
 
   m.Goto(&header);
 
   m.Bind(&header);
-  Node* i = m.Phi(kMachInt32, zero, zero);
-  Node* j = m.Phi(kMachInt32, zero, zero);
+  Node* i = m.Phi(MachineRepresentation::kWord32, zero, zero);
+  Node* j = m.Phi(MachineRepresentation::kWord32, zero, zero);
   m.Goto(&body);
 
   m.Bind(&body);
@@ -3709,14 +4445,14 @@
   Node* ten = m.Int32Constant(10);
   Node* one = m.Int32Constant(1);
 
-  MLabel header, body, body_cont, end;
+  RawMachineLabel header, body, body_cont, end;
 
   m.Goto(&header);
 
   m.Bind(&header);
-  Node* i = m.Phi(kMachInt32, zero, zero);
-  Node* j = m.Phi(kMachInt32, zero, zero);
-  Node* k = m.Phi(kMachInt32, zero, zero);
+  Node* i = m.Phi(MachineRepresentation::kWord32, zero, zero);
+  Node* j = m.Phi(MachineRepresentation::kWord32, zero, zero);
+  Node* k = m.Phi(MachineRepresentation::kWord32, zero, zero);
   m.Goto(&body);
 
   m.Bind(&body);
@@ -3743,14 +4479,22 @@
   int32_t inputs[] = {11, 12, 13, 14, 15, 16, 17, 18};
 
   Node* base = m.PointerConstant(inputs);
-  Node* n0 = m.Load(kMachInt32, base, m.Int32Constant(0 * sizeof(int32_t)));
-  Node* n1 = m.Load(kMachInt32, base, m.Int32Constant(1 * sizeof(int32_t)));
-  Node* n2 = m.Load(kMachInt32, base, m.Int32Constant(2 * sizeof(int32_t)));
-  Node* n3 = m.Load(kMachInt32, base, m.Int32Constant(3 * sizeof(int32_t)));
-  Node* n4 = m.Load(kMachInt32, base, m.Int32Constant(4 * sizeof(int32_t)));
-  Node* n5 = m.Load(kMachInt32, base, m.Int32Constant(5 * sizeof(int32_t)));
-  Node* n6 = m.Load(kMachInt32, base, m.Int32Constant(6 * sizeof(int32_t)));
-  Node* n7 = m.Load(kMachInt32, base, m.Int32Constant(7 * sizeof(int32_t)));
+  Node* n0 =
+      m.Load(MachineType::Int32(), base, m.Int32Constant(0 * sizeof(int32_t)));
+  Node* n1 =
+      m.Load(MachineType::Int32(), base, m.Int32Constant(1 * sizeof(int32_t)));
+  Node* n2 =
+      m.Load(MachineType::Int32(), base, m.Int32Constant(2 * sizeof(int32_t)));
+  Node* n3 =
+      m.Load(MachineType::Int32(), base, m.Int32Constant(3 * sizeof(int32_t)));
+  Node* n4 =
+      m.Load(MachineType::Int32(), base, m.Int32Constant(4 * sizeof(int32_t)));
+  Node* n5 =
+      m.Load(MachineType::Int32(), base, m.Int32Constant(5 * sizeof(int32_t)));
+  Node* n6 =
+      m.Load(MachineType::Int32(), base, m.Int32Constant(6 * sizeof(int32_t)));
+  Node* n7 =
+      m.Load(MachineType::Int32(), base, m.Int32Constant(7 * sizeof(int32_t)));
 
   Node* i1 = m.Int32Add(n0, n1);
   Node* i2 = m.Int32Add(n2, n3);
@@ -3782,10 +4526,12 @@
   CHECK(x < y);
   bool load_a = node_type / 2 == 1;
   bool load_b = node_type % 2 == 1;
-  Node* a = load_a ? m->Load(kMachFloat64, m->PointerConstant(&buffer[0]))
-                   : m->Float64Constant(x);
-  Node* b = load_b ? m->Load(kMachFloat64, m->PointerConstant(&buffer[1]))
-                   : m->Float64Constant(y);
+  Node* a =
+      load_a ? m->Load(MachineType::Float64(), m->PointerConstant(&buffer[0]))
+             : m->Float64Constant(x);
+  Node* b =
+      load_b ? m->Load(MachineType::Float64(), m->PointerConstant(&buffer[1]))
+             : m->Float64Constant(y);
   Node* cmp = NULL;
   bool expected = false;
   switch (test_case) {
@@ -3890,7 +4636,7 @@
                                  m.machine()->Float64LessThan(),
                                  m.machine()->Float64LessThanOrEqual()};
 
-  double nan = v8::base::OS::nan_value();
+  double nan = std::numeric_limits<double>::quiet_NaN();
 
   FOR_FLOAT64_INPUTS(i) {
     for (size_t o = 0; o < arraysize(operators); ++o) {
@@ -3899,7 +4645,7 @@
         Node* a = m.Float64Constant(*i);
         Node* b = m.Float64Constant(nan);
         if (j == 1) std::swap(a, b);
-        m.Return(m.NewNode(operators[o], a, b));
+        m.Return(m.AddNode(operators[o], a, b));
         CHECK_EQ(0, m.Call());
       }
     }
@@ -3912,8 +4658,8 @@
   double input_b = 0.0;
 
   RawMachineAssemblerTester<int32_t> m;
-  Node* a = m.LoadFromPointer(&input_a, kMachFloat64);
-  Node* b = m.LoadFromPointer(&input_b, kMachFloat64);
+  Node* a = m.LoadFromPointer(&input_a, MachineType::Float64());
+  Node* b = m.LoadFromPointer(&input_b, MachineType::Float64());
   m.Return(m.Float64Equal(a, b));
 
   CompareWrapper cmp(IrOpcode::kFloat64Equal);
@@ -3933,8 +4679,8 @@
   double input_b = 0.0;
 
   RawMachineAssemblerTester<int32_t> m;
-  Node* a = m.LoadFromPointer(&input_a, kMachFloat64);
-  Node* b = m.LoadFromPointer(&input_b, kMachFloat64);
+  Node* a = m.LoadFromPointer(&input_a, MachineType::Float64());
+  Node* b = m.LoadFromPointer(&input_b, MachineType::Float64());
   m.Return(m.Float64LessThan(a, b));
 
   CompareWrapper cmp(IrOpcode::kFloat64LessThan);
@@ -3949,14 +4695,14 @@
 }
 
 
-template <typename IntType, MachineType kRepresentation>
-static void LoadStoreTruncation() {
+template <typename IntType>
+static void LoadStoreTruncation(MachineType kRepresentation) {
   IntType input;
 
   RawMachineAssemblerTester<int32_t> m;
   Node* a = m.LoadFromPointer(&input, kRepresentation);
   Node* ap1 = m.Int32Add(a, m.Int32Constant(1));
-  m.StoreToPointer(&input, kRepresentation, ap1);
+  m.StoreToPointer(&input, kRepresentation.representation(), ap1);
   m.Return(ap1);
 
   const IntType max = std::numeric_limits<IntType>::max();
@@ -3983,14 +4729,15 @@
 
 
 TEST(RunLoadStoreTruncation) {
-  LoadStoreTruncation<int8_t, kMachInt8>();
-  LoadStoreTruncation<int16_t, kMachInt16>();
+  LoadStoreTruncation<int8_t>(MachineType::Int8());
+  LoadStoreTruncation<int16_t>(MachineType::Int16());
 }
 
 
 static void IntPtrCompare(intptr_t left, intptr_t right) {
   for (int test = 0; test < 7; test++) {
-    RawMachineAssemblerTester<bool> m(kMachPtr, kMachPtr);
+    RawMachineAssemblerTester<bool> m(MachineType::Pointer(),
+                                      MachineType::Pointer());
     Node* p0 = m.Parameter(0);
     Node* p1 = m.Parameter(1);
     Node* res = NULL;
@@ -4057,9 +4804,10 @@
   RawMachineAssemblerTester<int32_t*> m;
   Node* input = m.PointerConstant(&inputs[0]);
   Node* output = m.PointerConstant(&outputs[kInputSize - 1]);
-  Node* elem_size = m.ConvertInt32ToIntPtr(m.Int32Constant(sizeof(inputs[0])));
+  Node* elem_size = m.IntPtrConstant(sizeof(inputs[0]));
   for (int i = 0; i < kInputSize; i++) {
-    m.Store(kMachInt32, output, m.Load(kMachInt32, input));
+    m.Store(MachineRepresentation::kWord32, output,
+            m.Load(MachineType::Int32(), input), kNoWriteBarrier);
     input = m.IntPtrAdd(input, elem_size);
     output = m.IntPtrSub(output, elem_size);
   }
@@ -4074,7 +4822,7 @@
 
 TEST(RunSpillLotsOfThings) {
   static const int kInputSize = 1000;
-  RawMachineAssemblerTester<void> m;
+  RawMachineAssemblerTester<int32_t> m;
   Node* accs[kInputSize];
   int32_t outputs[kInputSize];
   Node* one = m.Int32Constant(1);
@@ -4084,7 +4832,7 @@
     accs[i] = acc;
   }
   for (int i = 0; i < kInputSize; i++) {
-    m.StoreToPointer(&outputs[i], kMachInt32, accs[i]);
+    m.StoreToPointer(&outputs[i], MachineRepresentation::kWord32, accs[i]);
   }
   m.Return(one);
   m.Call();
@@ -4097,7 +4845,8 @@
 TEST(RunSpillConstantsAndParameters) {
   static const int kInputSize = 1000;
   static const int32_t kBase = 987;
-  RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32);
+  RawMachineAssemblerTester<int32_t> m(MachineType::Int32(),
+                                       MachineType::Int32());
   int32_t outputs[kInputSize];
   Node* csts[kInputSize];
   Node* accs[kInputSize];
@@ -4110,7 +4859,7 @@
     accs[i] = acc;
   }
   for (int i = 0; i < kInputSize; i++) {
-    m.StoreToPointer(&outputs[i], kMachInt32, accs[i]);
+    m.StoreToPointer(&outputs[i], MachineRepresentation::kWord32, accs[i]);
   }
   m.Return(m.Int32Add(acc, m.Int32Add(m.Parameter(0), m.Parameter(1))));
   FOR_INT32_INPUTS(i) {
@@ -4131,7 +4880,7 @@
 
 
 TEST(RunNewSpaceConstantsInPhi) {
-  RawMachineAssemblerTester<Object*> m(kMachInt32);
+  RawMachineAssemblerTester<Object*> m(MachineType::Int32());
 
   Isolate* isolate = CcTest::i_isolate();
   Handle<HeapNumber> true_val = isolate->factory()->NewHeapNumber(11.2);
@@ -4139,7 +4888,7 @@
   Node* true_node = m.HeapConstant(true_val);
   Node* false_node = m.HeapConstant(false_val);
 
-  MLabel blocka, blockb, end;
+  RawMachineLabel blocka, blockb, end;
   m.Branch(m.Parameter(0), &blocka, &blockb);
   m.Bind(&blocka);
   m.Goto(&end);
@@ -4147,7 +4896,7 @@
   m.Goto(&end);
 
   m.Bind(&end);
-  Node* phi = m.Phi(kMachAnyTagged, true_node, false_node);
+  Node* phi = m.Phi(MachineRepresentation::kTagged, true_node, false_node);
   m.Return(phi);
 
   CHECK_EQ(*false_val, m.Call(0));
@@ -4162,7 +4911,7 @@
   Node* add = m.Int32AddWithOverflow(bt.param0, bt.param1);
   Node* val = m.Projection(0, add);
   Node* ovf = m.Projection(1, add);
-  m.StoreToPointer(&actual_val, kMachInt32, val);
+  m.StoreToPointer(&actual_val, MachineRepresentation::kWord32, val);
   bt.AddReturn(ovf);
   FOR_INT32_INPUTS(i) {
     FOR_INT32_INPUTS(j) {
@@ -4179,11 +4928,11 @@
   int32_t actual_val = -1, expected_val = 0;
   FOR_INT32_INPUTS(i) {
     {
-      RawMachineAssemblerTester<int32_t> m(kMachInt32);
+      RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
       Node* add = m.Int32AddWithOverflow(m.Int32Constant(*i), m.Parameter(0));
       Node* val = m.Projection(0, add);
       Node* ovf = m.Projection(1, add);
-      m.StoreToPointer(&actual_val, kMachInt32, val);
+      m.StoreToPointer(&actual_val, MachineRepresentation::kWord32, val);
       m.Return(ovf);
       FOR_INT32_INPUTS(j) {
         int expected_ovf = bits::SignedAddOverflow32(*i, *j, &expected_val);
@@ -4192,11 +4941,11 @@
       }
     }
     {
-      RawMachineAssemblerTester<int32_t> m(kMachInt32);
+      RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
       Node* add = m.Int32AddWithOverflow(m.Parameter(0), m.Int32Constant(*i));
       Node* val = m.Projection(0, add);
       Node* ovf = m.Projection(1, add);
-      m.StoreToPointer(&actual_val, kMachInt32, val);
+      m.StoreToPointer(&actual_val, MachineRepresentation::kWord32, val);
       m.Return(ovf);
       FOR_INT32_INPUTS(j) {
         int expected_ovf = bits::SignedAddOverflow32(*i, *j, &expected_val);
@@ -4210,7 +4959,7 @@
           m.Int32AddWithOverflow(m.Int32Constant(*i), m.Int32Constant(*j));
       Node* val = m.Projection(0, add);
       Node* ovf = m.Projection(1, add);
-      m.StoreToPointer(&actual_val, kMachInt32, val);
+      m.StoreToPointer(&actual_val, MachineRepresentation::kWord32, val);
       m.Return(ovf);
       int expected_ovf = bits::SignedAddOverflow32(*i, *j, &expected_val);
       CHECK_EQ(expected_ovf, m.Call());
@@ -4222,7 +4971,7 @@
 
 TEST(RunInt32AddWithOverflowInBranchP) {
   int constant = 911777;
-  MLabel blocka, blockb;
+  RawMachineLabel blocka, blockb;
   RawMachineAssemblerTester<int32_t> m;
   Int32BinopTester bt(&m);
   Node* add = m.Int32AddWithOverflow(bt.param0, bt.param1);
@@ -4250,7 +4999,7 @@
   Node* add = m.Int32SubWithOverflow(bt.param0, bt.param1);
   Node* val = m.Projection(0, add);
   Node* ovf = m.Projection(1, add);
-  m.StoreToPointer(&actual_val, kMachInt32, val);
+  m.StoreToPointer(&actual_val, MachineRepresentation::kWord32, val);
   bt.AddReturn(ovf);
   FOR_INT32_INPUTS(i) {
     FOR_INT32_INPUTS(j) {
@@ -4267,11 +5016,11 @@
   int32_t actual_val = -1, expected_val = 0;
   FOR_INT32_INPUTS(i) {
     {
-      RawMachineAssemblerTester<int32_t> m(kMachInt32);
+      RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
       Node* add = m.Int32SubWithOverflow(m.Int32Constant(*i), m.Parameter(0));
       Node* val = m.Projection(0, add);
       Node* ovf = m.Projection(1, add);
-      m.StoreToPointer(&actual_val, kMachInt32, val);
+      m.StoreToPointer(&actual_val, MachineRepresentation::kWord32, val);
       m.Return(ovf);
       FOR_INT32_INPUTS(j) {
         int expected_ovf = bits::SignedSubOverflow32(*i, *j, &expected_val);
@@ -4280,11 +5029,11 @@
       }
     }
     {
-      RawMachineAssemblerTester<int32_t> m(kMachInt32);
+      RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
       Node* add = m.Int32SubWithOverflow(m.Parameter(0), m.Int32Constant(*i));
       Node* val = m.Projection(0, add);
       Node* ovf = m.Projection(1, add);
-      m.StoreToPointer(&actual_val, kMachInt32, val);
+      m.StoreToPointer(&actual_val, MachineRepresentation::kWord32, val);
       m.Return(ovf);
       FOR_INT32_INPUTS(j) {
         int expected_ovf = bits::SignedSubOverflow32(*j, *i, &expected_val);
@@ -4298,7 +5047,7 @@
           m.Int32SubWithOverflow(m.Int32Constant(*i), m.Int32Constant(*j));
       Node* val = m.Projection(0, add);
       Node* ovf = m.Projection(1, add);
-      m.StoreToPointer(&actual_val, kMachInt32, val);
+      m.StoreToPointer(&actual_val, MachineRepresentation::kWord32, val);
       m.Return(ovf);
       int expected_ovf = bits::SignedSubOverflow32(*i, *j, &expected_val);
       CHECK_EQ(expected_ovf, m.Call());
@@ -4310,7 +5059,7 @@
 
 TEST(RunInt32SubWithOverflowInBranchP) {
   int constant = 911999;
-  MLabel blocka, blockb;
+  RawMachineLabel blocka, blockb;
   RawMachineAssemblerTester<int32_t> m;
   Int32BinopTester bt(&m);
   Node* sub = m.Int32SubWithOverflow(bt.param0, bt.param1);
@@ -4331,11 +5080,32 @@
 }
 
 
+TEST(RunWord64EqualInBranchP) {
+  int64_t input;
+  RawMachineLabel blocka, blockb;
+  RawMachineAssemblerTester<int64_t> m;
+  if (!m.machine()->Is64()) return;
+  Node* value = m.LoadFromPointer(&input, MachineType::Int64());
+  m.Branch(m.Word64Equal(value, m.Int64Constant(0)), &blocka, &blockb);
+  m.Bind(&blocka);
+  m.Return(m.Int32Constant(1));
+  m.Bind(&blockb);
+  m.Return(m.Int32Constant(2));
+  input = V8_INT64_C(0);
+  CHECK_EQ(1, m.Call());
+  input = V8_INT64_C(1);
+  CHECK_EQ(2, m.Call());
+  input = V8_INT64_C(0x100000000);
+  CHECK_EQ(2, m.Call());
+}
+
+
 TEST(RunChangeInt32ToInt64P) {
   if (kPointerSize < 8) return;
   int64_t actual = -1;
-  RawMachineAssemblerTester<int32_t> m(kMachInt32);
-  m.StoreToPointer(&actual, kMachInt64, m.ChangeInt32ToInt64(m.Parameter(0)));
+  RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
+  m.StoreToPointer(&actual, MachineRepresentation::kWord64,
+                   m.ChangeInt32ToInt64(m.Parameter(0)));
   m.Return(m.Int32Constant(0));
   FOR_INT32_INPUTS(i) {
     int64_t expected = *i;
@@ -4348,8 +5118,8 @@
 TEST(RunChangeUint32ToUint64P) {
   if (kPointerSize < 8) return;
   int64_t actual = -1;
-  RawMachineAssemblerTester<int32_t> m(kMachUint32);
-  m.StoreToPointer(&actual, kMachUint64,
+  RawMachineAssemblerTester<int32_t> m(MachineType::Uint32());
+  m.StoreToPointer(&actual, MachineRepresentation::kWord64,
                    m.ChangeUint32ToUint64(m.Parameter(0)));
   m.Return(m.Int32Constant(0));
   FOR_UINT32_INPUTS(i) {
@@ -4364,11 +5134,12 @@
   if (kPointerSize < 8) return;
   int64_t expected = -1;
   RawMachineAssemblerTester<int32_t> m;
-  m.Return(m.TruncateInt64ToInt32(m.LoadFromPointer(&expected, kMachInt64)));
+  m.Return(m.TruncateInt64ToInt32(
+      m.LoadFromPointer(&expected, MachineType::Int64())));
   FOR_UINT32_INPUTS(i) {
     FOR_UINT32_INPUTS(j) {
       expected = (static_cast<uint64_t>(*j) << 32) | *i;
-      CHECK_UINT32_EQ(expected, m.Call());
+      CHECK_EQ(static_cast<int32_t>(expected), m.Call());
     }
   }
 }
@@ -4385,9 +5156,9 @@
                  {-1.5, -1},
                  {5.5, 5},
                  {-5.0, -5},
-                 {v8::base::OS::nan_value(), 0},
+                 {std::numeric_limits<double>::quiet_NaN(), 0},
                  {std::numeric_limits<double>::infinity(), 0},
-                 {-v8::base::OS::nan_value(), 0},
+                 {-std::numeric_limits<double>::quiet_NaN(), 0},
                  {-std::numeric_limits<double>::infinity(), 0},
                  {4.94065645841e-324, 0},
                  {-4.94065645841e-324, 0},
@@ -4435,7 +5206,9 @@
                  {-1.7976931348623157e+308, 0}};
   double input = -1.0;
   RawMachineAssemblerTester<int32_t> m;
-  m.Return(m.TruncateFloat64ToInt32(m.LoadFromPointer(&input, kMachFloat64)));
+  m.Return(m.TruncateFloat64ToInt32(
+      TruncationMode::kJavaScript,
+      m.LoadFromPointer(&input, MachineType::Float64())));
   for (size_t i = 0; i < arraysize(kValues); ++i) {
     input = kValues[i].from;
     uint64_t expected = static_cast<int64_t>(kValues[i].raw);
@@ -4445,83 +5218,87 @@
 
 
 TEST(RunChangeFloat32ToFloat64) {
-  double actual = 0.0f;
-  float expected = 0.0;
-  RawMachineAssemblerTester<int32_t> m;
-  m.StoreToPointer(
-      &actual, kMachFloat64,
-      m.ChangeFloat32ToFloat64(m.LoadFromPointer(&expected, kMachFloat32)));
-  m.Return(m.Int32Constant(0));
-  FOR_FLOAT32_INPUTS(i) {
-    expected = *i;
-    CHECK_EQ(0, m.Call());
-    CHECK_EQ(expected, actual);
-  }
-}
+  BufferedRawMachineAssemblerTester<double> m(MachineType::Float32());
 
+  m.Return(m.ChangeFloat32ToFloat64(m.Parameter(0)));
 
-TEST(RunChangeFloat32ToFloat64_spilled) {
-  RawMachineAssemblerTester<int32_t> m;
-  const int kNumInputs = 32;
-  int32_t magic = 0x786234;
-  float input[kNumInputs];
-  double result[kNumInputs];
-  Node* input_node[kNumInputs];
-
-  for (int i = 0; i < kNumInputs; i++) {
-    input_node[i] =
-        m.Load(kMachFloat32, m.PointerConstant(&input), m.Int32Constant(i * 4));
-  }
-
-  for (int i = 0; i < kNumInputs; i++) {
-    m.Store(kMachFloat64, m.PointerConstant(&result), m.Int32Constant(i * 8),
-            m.ChangeFloat32ToFloat64(input_node[i]));
-  }
-
-  m.Return(m.Int32Constant(magic));
-
-  for (int i = 0; i < kNumInputs; i++) {
-    input[i] = 100.9f + i;
-  }
-
-  CHECK_EQ(magic, m.Call());
-
-  for (int i = 0; i < kNumInputs; i++) {
-    CHECK_EQ(result[i], static_cast<double>(input[i]));
-  }
-}
-
-
-TEST(RunTruncateFloat64ToFloat32) {
-  float actual = 0.0f;
-  double input = 0.0;
-  RawMachineAssemblerTester<int32_t> m;
-  m.StoreToPointer(
-      &actual, kMachFloat32,
-      m.TruncateFloat64ToFloat32(m.LoadFromPointer(&input, kMachFloat64)));
-  m.Return(m.Int32Constant(0));
-  FOR_FLOAT64_INPUTS(i) {
-    input = *i;
-    volatile double expected = DoubleToFloat32(input);
-    CHECK_EQ(0, m.Call());
-    CHECK_EQ(expected, actual);
-  }
+  FOR_FLOAT32_INPUTS(i) { CheckDoubleEq(static_cast<double>(*i), m.Call(*i)); }
 }
 
 
 TEST(RunFloat32Constant) {
   FOR_FLOAT32_INPUTS(i) {
-    float expected = *i;
-    float actual = *i;
-    RawMachineAssemblerTester<int32_t> m;
-    m.StoreToPointer(&actual, kMachFloat32, m.Float32Constant(expected));
-    m.Return(m.Int32Constant(0));
-    CHECK_EQ(0, m.Call());
-    CHECK_EQ(expected, actual);
+    BufferedRawMachineAssemblerTester<float> m;
+    m.Return(m.Float32Constant(*i));
+    CheckFloatEq(*i, m.Call());
   }
 }
 
 
+TEST(RunFloat64ExtractLowWord32) {
+  BufferedRawMachineAssemblerTester<uint32_t> m(MachineType::Float64());
+  m.Return(m.Float64ExtractLowWord32(m.Parameter(0)));
+  FOR_FLOAT64_INPUTS(i) {
+    uint32_t expected = static_cast<uint32_t>(bit_cast<uint64_t>(*i));
+    CHECK_EQ(expected, m.Call(*i));
+  }
+}
+
+
+TEST(RunFloat64ExtractHighWord32) {
+  BufferedRawMachineAssemblerTester<uint32_t> m(MachineType::Float64());
+  m.Return(m.Float64ExtractHighWord32(m.Parameter(0)));
+  FOR_FLOAT64_INPUTS(i) {
+    uint32_t expected = static_cast<uint32_t>(bit_cast<uint64_t>(*i) >> 32);
+    CHECK_EQ(expected, m.Call(*i));
+  }
+}
+
+
+TEST(RunFloat64InsertLowWord32) {
+  BufferedRawMachineAssemblerTester<double> m(MachineType::Float64(),
+                                              MachineType::Int32());
+  m.Return(m.Float64InsertLowWord32(m.Parameter(0), m.Parameter(1)));
+  FOR_FLOAT64_INPUTS(i) {
+    FOR_INT32_INPUTS(j) {
+      double expected = bit_cast<double>(
+          (bit_cast<uint64_t>(*i) & ~(V8_UINT64_C(0xFFFFFFFF))) |
+          (static_cast<uint64_t>(bit_cast<uint32_t>(*j))));
+      CheckDoubleEq(expected, m.Call(*i, *j));
+    }
+  }
+}
+
+
+TEST(RunFloat64InsertHighWord32) {
+  BufferedRawMachineAssemblerTester<double> m(MachineType::Float64(),
+                                              MachineType::Uint32());
+  m.Return(m.Float64InsertHighWord32(m.Parameter(0), m.Parameter(1)));
+  FOR_FLOAT64_INPUTS(i) {
+    FOR_UINT32_INPUTS(j) {
+      uint64_t expected = (bit_cast<uint64_t>(*i) & 0xFFFFFFFF) |
+                          (static_cast<uint64_t>(*j) << 32);
+
+      CheckDoubleEq(bit_cast<double>(expected), m.Call(*i, *j));
+    }
+  }
+}
+
+
+TEST(RunFloat32Abs) {
+  BufferedRawMachineAssemblerTester<float> m(MachineType::Float32());
+  m.Return(m.Float32Abs(m.Parameter(0)));
+  FOR_FLOAT32_INPUTS(i) { CheckFloatEq(std::abs(*i), m.Call(*i)); }
+}
+
+
+TEST(RunFloat64Abs) {
+  BufferedRawMachineAssemblerTester<double> m(MachineType::Float64());
+  m.Return(m.Float64Abs(m.Parameter(0)));
+  FOR_FLOAT64_INPUTS(i) { CheckDoubleEq(std::abs(*i), m.Call(*i)); }
+}
+
+
 static double two_30 = 1 << 30;             // 2^30 is a smi boundary.
 static double two_52 = two_30 * (1 << 22);  // 2^52 is a precision boundary.
 static double kValues[] = {0.1,
@@ -4620,72 +5397,677 @@
                            -two_52 + 1 - 0.7};
 
 
-TEST(RunFloat64Floor) {
-  double input = -1.0;
-  double result = 0.0;
-  RawMachineAssemblerTester<int32_t> m;
-  if (!m.machine()->HasFloat64Floor()) return;
-  m.StoreToPointer(&result, kMachFloat64,
-                   m.Float64Floor(m.LoadFromPointer(&input, kMachFloat64)));
-  m.Return(m.Int32Constant(0));
+TEST(RunFloat32RoundDown) {
+  BufferedRawMachineAssemblerTester<float> m(MachineType::Float32());
+  if (!m.machine()->Float32RoundDown().IsSupported()) return;
+
+  m.Return(m.Float32RoundDown(m.Parameter(0)));
+
+  FOR_FLOAT32_INPUTS(i) { CheckFloatEq(floorf(*i), m.Call(*i)); }
+}
+
+
+TEST(RunFloat64RoundDown1) {
+  BufferedRawMachineAssemblerTester<double> m(MachineType::Float64());
+  if (!m.machine()->Float64RoundDown().IsSupported()) return;
+
+  m.Return(m.Float64RoundDown(m.Parameter(0)));
+
+  FOR_FLOAT64_INPUTS(i) { CheckDoubleEq(floor(*i), m.Call(*i)); }
+}
+
+
+TEST(RunFloat64RoundDown2) {
+  BufferedRawMachineAssemblerTester<double> m(MachineType::Float64());
+  if (!m.machine()->Float64RoundDown().IsSupported()) return;
+  m.Return(m.Float64Sub(m.Float64Constant(-0.0),
+                        m.Float64RoundDown(m.Float64Sub(m.Float64Constant(-0.0),
+                                                        m.Parameter(0)))));
+
   for (size_t i = 0; i < arraysize(kValues); ++i) {
-    input = kValues[i];
-    CHECK_EQ(0, m.Call());
-    double expected = std::floor(kValues[i]);
-    CHECK_EQ(expected, result);
+    CHECK_EQ(ceil(kValues[i]), m.Call(kValues[i]));
   }
 }
 
 
-TEST(RunFloat64Ceil) {
-  double input = -1.0;
-  double result = 0.0;
-  RawMachineAssemblerTester<int32_t> m;
-  if (!m.machine()->HasFloat64Ceil()) return;
-  m.StoreToPointer(&result, kMachFloat64,
-                   m.Float64Ceil(m.LoadFromPointer(&input, kMachFloat64)));
-  m.Return(m.Int32Constant(0));
-  for (size_t i = 0; i < arraysize(kValues); ++i) {
-    input = kValues[i];
-    CHECK_EQ(0, m.Call());
-    double expected = std::ceil(kValues[i]);
-    CHECK_EQ(expected, result);
-  }
+TEST(RunFloat32RoundUp) {
+  BufferedRawMachineAssemblerTester<float> m(MachineType::Float32());
+  if (!m.machine()->Float32RoundUp().IsSupported()) return;
+  m.Return(m.Float32RoundUp(m.Parameter(0)));
+
+  FOR_FLOAT32_INPUTS(i) { CheckFloatEq(ceilf(*i), m.Call(*i)); }
+}
+
+
+TEST(RunFloat64RoundUp) {
+  BufferedRawMachineAssemblerTester<double> m(MachineType::Float64());
+  if (!m.machine()->Float64RoundUp().IsSupported()) return;
+  m.Return(m.Float64RoundUp(m.Parameter(0)));
+
+  FOR_FLOAT64_INPUTS(i) { CheckDoubleEq(ceil(*i), m.Call(*i)); }
+}
+
+
+TEST(RunFloat32RoundTiesEven) {
+  BufferedRawMachineAssemblerTester<float> m(MachineType::Float32());
+  if (!m.machine()->Float32RoundTiesEven().IsSupported()) return;
+  m.Return(m.Float32RoundTiesEven(m.Parameter(0)));
+
+  FOR_FLOAT32_INPUTS(i) { CheckFloatEq(nearbyint(*i), m.Call(*i)); }
+}
+
+
+TEST(RunFloat64RoundTiesEven) {
+  BufferedRawMachineAssemblerTester<double> m(MachineType::Float64());
+  if (!m.machine()->Float64RoundTiesEven().IsSupported()) return;
+  m.Return(m.Float64RoundTiesEven(m.Parameter(0)));
+
+  FOR_FLOAT64_INPUTS(i) { CheckDoubleEq(nearbyint(*i), m.Call(*i)); }
+}
+
+
+TEST(RunFloat32RoundTruncate) {
+  BufferedRawMachineAssemblerTester<float> m(MachineType::Float32());
+  if (!m.machine()->Float32RoundTruncate().IsSupported()) return;
+
+  m.Return(m.Float32RoundTruncate(m.Parameter(0)));
+
+  FOR_FLOAT32_INPUTS(i) { CheckFloatEq(truncf(*i), m.Call(*i)); }
 }
 
 
 TEST(RunFloat64RoundTruncate) {
-  double input = -1.0;
-  double result = 0.0;
-  RawMachineAssemblerTester<int32_t> m;
-  if (!m.machine()->HasFloat64Ceil()) return;
-  m.StoreToPointer(
-      &result, kMachFloat64,
-      m.Float64RoundTruncate(m.LoadFromPointer(&input, kMachFloat64)));
-  m.Return(m.Int32Constant(0));
+  BufferedRawMachineAssemblerTester<double> m(MachineType::Float64());
+  if (!m.machine()->Float64RoundTruncate().IsSupported()) return;
+  m.Return(m.Float64RoundTruncate(m.Parameter(0)));
   for (size_t i = 0; i < arraysize(kValues); ++i) {
-    input = kValues[i];
-    CHECK_EQ(0, m.Call());
-    double expected = trunc(kValues[i]);
-    CHECK_EQ(expected, result);
+    CHECK_EQ(trunc(kValues[i]), m.Call(kValues[i]));
   }
 }
 
 
 TEST(RunFloat64RoundTiesAway) {
-  double input = -1.0;
-  double result = 0.0;
-  RawMachineAssemblerTester<int32_t> m;
-  if (!m.machine()->HasFloat64RoundTiesAway()) return;
-  m.StoreToPointer(
-      &result, kMachFloat64,
-      m.Float64RoundTiesAway(m.LoadFromPointer(&input, kMachFloat64)));
-  m.Return(m.Int32Constant(0));
+  BufferedRawMachineAssemblerTester<double> m(MachineType::Float64());
+  if (!m.machine()->Float64RoundTiesAway().IsSupported()) return;
+  m.Return(m.Float64RoundTiesAway(m.Parameter(0)));
   for (size_t i = 0; i < arraysize(kValues); ++i) {
-    input = kValues[i];
-    CHECK_EQ(0, m.Call());
-    double expected = round(kValues[i]);
-    CHECK_EQ(expected, result);
+    CHECK_EQ(round(kValues[i]), m.Call(kValues[i]));
   }
 }
-#endif  // V8_TURBOFAN_TARGET
+
+
+#if !USE_SIMULATOR
+
+namespace {
+
+int32_t const kMagicFoo0 = 0xdeadbeef;
+
+
+int32_t foo0() { return kMagicFoo0; }
+
+
+int32_t foo1(int32_t x) { return x; }
+
+
+int32_t foo2(int32_t x, int32_t y) { return x - y; }
+
+
+int32_t foo8(int32_t a, int32_t b, int32_t c, int32_t d, int32_t e, int32_t f,
+             int32_t g, int32_t h) {
+  return a + b + c + d + e + f + g + h;
+}
+
+}  // namespace
+
+
+TEST(RunCallCFunction0) {
+  auto* foo0_ptr = &foo0;
+  RawMachineAssemblerTester<int32_t> m;
+  Node* function = m.LoadFromPointer(&foo0_ptr, MachineType::Pointer());
+  m.Return(m.CallCFunction0(MachineType::Int32(), function));
+  CHECK_EQ(kMagicFoo0, m.Call());
+}
+
+
+TEST(RunCallCFunction1) {
+  auto* foo1_ptr = &foo1;
+  RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
+  Node* function = m.LoadFromPointer(&foo1_ptr, MachineType::Pointer());
+  m.Return(m.CallCFunction1(MachineType::Int32(), MachineType::Int32(),
+                            function, m.Parameter(0)));
+  FOR_INT32_INPUTS(i) {
+    int32_t const expected = *i;
+    CHECK_EQ(expected, m.Call(expected));
+  }
+}
+
+
+TEST(RunCallCFunction2) {
+  auto* foo2_ptr = &foo2;
+  RawMachineAssemblerTester<int32_t> m(MachineType::Int32(),
+                                       MachineType::Int32());
+  Node* function = m.LoadFromPointer(&foo2_ptr, MachineType::Pointer());
+  m.Return(m.CallCFunction2(MachineType::Int32(), MachineType::Int32(),
+                            MachineType::Int32(), function, m.Parameter(0),
+                            m.Parameter(1)));
+  FOR_INT32_INPUTS(i) {
+    int32_t const x = *i;
+    FOR_INT32_INPUTS(j) {
+      int32_t const y = *j;
+      CHECK_EQ(x - y, m.Call(x, y));
+    }
+  }
+}
+
+
+TEST(RunCallCFunction8) {
+  auto* foo8_ptr = &foo8;
+  RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
+  Node* function = m.LoadFromPointer(&foo8_ptr, MachineType::Pointer());
+  Node* param = m.Parameter(0);
+  m.Return(m.CallCFunction8(
+      MachineType::Int32(), MachineType::Int32(), MachineType::Int32(),
+      MachineType::Int32(), MachineType::Int32(), MachineType::Int32(),
+      MachineType::Int32(), MachineType::Int32(), MachineType::Int32(),
+      function, param, param, param, param, param, param, param, param));
+  FOR_INT32_INPUTS(i) {
+    int32_t const x = *i;
+    CHECK_EQ(x * 8, m.Call(x));
+  }
+}
+#endif  // USE_SIMULATOR
+
+#if V8_TARGET_ARCH_64_BIT
+// TODO(titzer): run int64 tests on all platforms when supported.
+TEST(RunCheckedLoadInt64) {
+  int64_t buffer[] = {0x66bbccddeeff0011LL, 0x1122334455667788LL};
+  RawMachineAssemblerTester<int64_t> m(MachineType::Int32());
+  Node* base = m.PointerConstant(buffer);
+  Node* index = m.Parameter(0);
+  Node* length = m.Int32Constant(16);
+  Node* load = m.AddNode(m.machine()->CheckedLoad(MachineType::Int64()), base,
+                         index, length);
+  m.Return(load);
+
+  CHECK_EQ(buffer[0], m.Call(0));
+  CHECK_EQ(buffer[1], m.Call(8));
+  CHECK_EQ(0, m.Call(16));
+}
+
+
+TEST(RunCheckedStoreInt64) {
+  const int64_t write = 0x5566778899aabbLL;
+  const int64_t before = 0x33bbccddeeff0011LL;
+  int64_t buffer[] = {before, before};
+  RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
+  Node* base = m.PointerConstant(buffer);
+  Node* index = m.Parameter(0);
+  Node* length = m.Int32Constant(16);
+  Node* value = m.Int64Constant(write);
+  Node* store =
+      m.AddNode(m.machine()->CheckedStore(MachineRepresentation::kWord64), base,
+                index, length, value);
+  USE(store);
+  m.Return(m.Int32Constant(11));
+
+  CHECK_EQ(11, m.Call(16));
+  CHECK_EQ(before, buffer[0]);
+  CHECK_EQ(before, buffer[1]);
+
+  CHECK_EQ(11, m.Call(0));
+  CHECK_EQ(write, buffer[0]);
+  CHECK_EQ(before, buffer[1]);
+
+  CHECK_EQ(11, m.Call(8));
+  CHECK_EQ(write, buffer[0]);
+  CHECK_EQ(write, buffer[1]);
+}
+
+
+TEST(RunBitcastInt64ToFloat64) {
+  int64_t input = 1;
+  double output = 0.0;
+  RawMachineAssemblerTester<int32_t> m;
+  m.StoreToPointer(
+      &output, MachineRepresentation::kFloat64,
+      m.BitcastInt64ToFloat64(m.LoadFromPointer(&input, MachineType::Int64())));
+  m.Return(m.Int32Constant(11));
+  FOR_INT64_INPUTS(i) {
+    input = *i;
+    CHECK_EQ(11, m.Call());
+    double expected = bit_cast<double>(input);
+    CHECK_EQ(bit_cast<int64_t>(expected), bit_cast<int64_t>(output));
+  }
+}
+
+
+TEST(RunBitcastFloat64ToInt64) {
+  BufferedRawMachineAssemblerTester<int64_t> m(MachineType::Float64());
+
+  m.Return(m.BitcastFloat64ToInt64(m.Parameter(0)));
+  FOR_FLOAT64_INPUTS(i) { CHECK_EQ(bit_cast<int64_t>(*i), m.Call(*i)); }
+}
+
+
+TEST(RunTryTruncateFloat32ToInt64WithoutCheck) {
+  BufferedRawMachineAssemblerTester<int64_t> m(MachineType::Float32());
+  m.Return(m.TryTruncateFloat32ToInt64(m.Parameter(0)));
+
+  FOR_INT64_INPUTS(i) {
+    float input = static_cast<float>(*i);
+    if (input < static_cast<float>(INT64_MAX) &&
+        input >= static_cast<float>(INT64_MIN)) {
+      CHECK_EQ(static_cast<int64_t>(input), m.Call(input));
+    }
+  }
+}
+
+
+TEST(RunTryTruncateFloat32ToInt64WithCheck) {
+  int64_t success = 0;
+  BufferedRawMachineAssemblerTester<int64_t> m(MachineType::Float32());
+  Node* trunc = m.TryTruncateFloat32ToInt64(m.Parameter(0));
+  Node* val = m.Projection(0, trunc);
+  Node* check = m.Projection(1, trunc);
+  m.StoreToPointer(&success, MachineRepresentation::kWord64, check);
+  m.Return(val);
+
+  FOR_FLOAT32_INPUTS(i) {
+    if (*i < static_cast<float>(INT64_MAX) &&
+        *i >= static_cast<float>(INT64_MIN)) {
+      CHECK_EQ(static_cast<int64_t>(*i), m.Call(*i));
+      CHECK_NE(0, success);
+    } else {
+      m.Call(*i);
+      CHECK_EQ(0, success);
+    }
+  }
+}
+
+
+TEST(RunTryTruncateFloat64ToInt64WithoutCheck) {
+  BufferedRawMachineAssemblerTester<int64_t> m(MachineType::Float64());
+  m.Return(m.TryTruncateFloat64ToInt64(m.Parameter(0)));
+
+  FOR_INT64_INPUTS(i) {
+    double input = static_cast<double>(*i);
+    CHECK_EQ(static_cast<int64_t>(input), m.Call(input));
+  }
+}
+
+
+TEST(RunTryTruncateFloat64ToInt64WithCheck) {
+  int64_t success = 0;
+  BufferedRawMachineAssemblerTester<int64_t> m(MachineType::Float64());
+  Node* trunc = m.TryTruncateFloat64ToInt64(m.Parameter(0));
+  Node* val = m.Projection(0, trunc);
+  Node* check = m.Projection(1, trunc);
+  m.StoreToPointer(&success, MachineRepresentation::kWord64, check);
+  m.Return(val);
+
+  FOR_FLOAT64_INPUTS(i) {
+    if (*i < static_cast<double>(INT64_MAX) &&
+        *i >= static_cast<double>(INT64_MIN)) {
+      // Conversions within this range should succeed.
+      CHECK_EQ(static_cast<int64_t>(*i), m.Call(*i));
+      CHECK_NE(0, success);
+    } else {
+      m.Call(*i);
+      CHECK_EQ(0, success);
+    }
+  }
+}
+
+
+TEST(RunTryTruncateFloat32ToUint64WithoutCheck) {
+  BufferedRawMachineAssemblerTester<uint64_t> m(MachineType::Float32());
+  m.Return(m.TryTruncateFloat32ToUint64(m.Parameter(0)));
+
+  FOR_UINT64_INPUTS(i) {
+    float input = static_cast<float>(*i);
+    // This condition on 'input' is required because
+    // static_cast<float>(UINT64_MAX) results in a value outside uint64 range.
+    if (input < static_cast<float>(UINT64_MAX)) {
+      CHECK_EQ(static_cast<uint64_t>(input), m.Call(input));
+    }
+  }
+}
+
+
+TEST(RunTryTruncateFloat32ToUint64WithCheck) {
+  int64_t success = 0;
+  BufferedRawMachineAssemblerTester<uint64_t> m(MachineType::Float32());
+  Node* trunc = m.TryTruncateFloat32ToUint64(m.Parameter(0));
+  Node* val = m.Projection(0, trunc);
+  Node* check = m.Projection(1, trunc);
+  m.StoreToPointer(&success, MachineRepresentation::kWord64, check);
+  m.Return(val);
+
+  FOR_FLOAT32_INPUTS(i) {
+    if (*i < static_cast<float>(UINT64_MAX) && *i > -1.0) {
+      // Conversions within this range should succeed.
+      CHECK_EQ(static_cast<uint64_t>(*i), m.Call(*i));
+      CHECK_NE(0, success);
+    } else {
+      m.Call(*i);
+      CHECK_EQ(0, success);
+    }
+  }
+}
+
+
+TEST(RunTryTruncateFloat64ToUint64WithoutCheck) {
+  BufferedRawMachineAssemblerTester<uint64_t> m(MachineType::Float64());
+  m.Return(m.TruncateFloat64ToUint64(m.Parameter(0)));
+
+  FOR_UINT64_INPUTS(j) {
+    double input = static_cast<double>(*j);
+
+    if (input < static_cast<float>(UINT64_MAX)) {
+      CHECK_EQ(static_cast<uint64_t>(input), m.Call(input));
+    }
+  }
+}
+
+
+TEST(RunTryTruncateFloat64ToUint64WithCheck) {
+  int64_t success = 0;
+  BufferedRawMachineAssemblerTester<int64_t> m(MachineType::Float64());
+  Node* trunc = m.TryTruncateFloat64ToUint64(m.Parameter(0));
+  Node* val = m.Projection(0, trunc);
+  Node* check = m.Projection(1, trunc);
+  m.StoreToPointer(&success, MachineRepresentation::kWord64, check);
+  m.Return(val);
+
+  FOR_FLOAT64_INPUTS(i) {
+    if (*i < 18446744073709551616.0 && *i > -1) {
+      // Conversions within this range should succeed.
+      CHECK_EQ(static_cast<uint64_t>(*i), m.Call(*i));
+      CHECK_NE(0, success);
+    } else {
+      m.Call(*i);
+      CHECK_EQ(0, success);
+    }
+  }
+}
+
+
+TEST(RunRoundInt64ToFloat32) {
+  BufferedRawMachineAssemblerTester<float> m(MachineType::Int64());
+  m.Return(m.RoundInt64ToFloat32(m.Parameter(0)));
+  FOR_INT64_INPUTS(i) { CHECK_EQ(static_cast<float>(*i), m.Call(*i)); }
+}
+
+
+TEST(RunRoundInt64ToFloat64) {
+  BufferedRawMachineAssemblerTester<double> m(MachineType::Int64());
+  m.Return(m.RoundInt64ToFloat64(m.Parameter(0)));
+  FOR_INT64_INPUTS(i) { CHECK_EQ(static_cast<double>(*i), m.Call(*i)); }
+}
+
+
+TEST(RunRoundUint64ToFloat64) {
+  struct {
+    uint64_t input;
+    uint64_t expected;
+  } values[] = {{0x0, 0x0},
+                {0x1, 0x3ff0000000000000},
+                {0xffffffff, 0x41efffffffe00000},
+                {0x1b09788b, 0x41bb09788b000000},
+                {0x4c5fce8, 0x419317f3a0000000},
+                {0xcc0de5bf, 0x41e981bcb7e00000},
+                {0x2, 0x4000000000000000},
+                {0x3, 0x4008000000000000},
+                {0x4, 0x4010000000000000},
+                {0x5, 0x4014000000000000},
+                {0x8, 0x4020000000000000},
+                {0x9, 0x4022000000000000},
+                {0xffffffffffffffff, 0x43f0000000000000},
+                {0xfffffffffffffffe, 0x43f0000000000000},
+                {0xfffffffffffffffd, 0x43f0000000000000},
+                {0x100000000, 0x41f0000000000000},
+                {0xffffffff00000000, 0x43efffffffe00000},
+                {0x1b09788b00000000, 0x43bb09788b000000},
+                {0x4c5fce800000000, 0x439317f3a0000000},
+                {0xcc0de5bf00000000, 0x43e981bcb7e00000},
+                {0x200000000, 0x4200000000000000},
+                {0x300000000, 0x4208000000000000},
+                {0x400000000, 0x4210000000000000},
+                {0x500000000, 0x4214000000000000},
+                {0x800000000, 0x4220000000000000},
+                {0x900000000, 0x4222000000000000},
+                {0x273a798e187937a3, 0x43c39d3cc70c3c9c},
+                {0xece3af835495a16b, 0x43ed9c75f06a92b4},
+                {0xb668ecc11223344, 0x43a6cd1d98224467},
+                {0x9e, 0x4063c00000000000},
+                {0x43, 0x4050c00000000000},
+                {0xaf73, 0x40e5ee6000000000},
+                {0x116b, 0x40b16b0000000000},
+                {0x658ecc, 0x415963b300000000},
+                {0x2b3b4c, 0x41459da600000000},
+                {0x88776655, 0x41e10eeccaa00000},
+                {0x70000000, 0x41dc000000000000},
+                {0x7200000, 0x419c800000000000},
+                {0x7fffffff, 0x41dfffffffc00000},
+                {0x56123761, 0x41d5848dd8400000},
+                {0x7fffff00, 0x41dfffffc0000000},
+                {0x761c4761eeeeeeee, 0x43dd8711d87bbbbc},
+                {0x80000000eeeeeeee, 0x43e00000001dddde},
+                {0x88888888dddddddd, 0x43e11111111bbbbc},
+                {0xa0000000dddddddd, 0x43e40000001bbbbc},
+                {0xddddddddaaaaaaaa, 0x43ebbbbbbbb55555},
+                {0xe0000000aaaaaaaa, 0x43ec000000155555},
+                {0xeeeeeeeeeeeeeeee, 0x43edddddddddddde},
+                {0xfffffffdeeeeeeee, 0x43efffffffbdddde},
+                {0xf0000000dddddddd, 0x43ee0000001bbbbc},
+                {0x7fffffdddddddd, 0x435ffffff7777777},
+                {0x3fffffaaaaaaaa, 0x434fffffd5555555},
+                {0x1fffffaaaaaaaa, 0x433fffffaaaaaaaa},
+                {0xfffff, 0x412ffffe00000000},
+                {0x7ffff, 0x411ffffc00000000},
+                {0x3ffff, 0x410ffff800000000},
+                {0x1ffff, 0x40fffff000000000},
+                {0xffff, 0x40efffe000000000},
+                {0x7fff, 0x40dfffc000000000},
+                {0x3fff, 0x40cfff8000000000},
+                {0x1fff, 0x40bfff0000000000},
+                {0xfff, 0x40affe0000000000},
+                {0x7ff, 0x409ffc0000000000},
+                {0x3ff, 0x408ff80000000000},
+                {0x1ff, 0x407ff00000000000},
+                {0x3fffffffffff, 0x42cfffffffffff80},
+                {0x1fffffffffff, 0x42bfffffffffff00},
+                {0xfffffffffff, 0x42affffffffffe00},
+                {0x7ffffffffff, 0x429ffffffffffc00},
+                {0x3ffffffffff, 0x428ffffffffff800},
+                {0x1ffffffffff, 0x427ffffffffff000},
+                {0x8000008000000000, 0x43e0000010000000},
+                {0x8000008000000001, 0x43e0000010000000},
+                {0x8000000000000400, 0x43e0000000000000},
+                {0x8000000000000401, 0x43e0000000000001}};
+
+  BufferedRawMachineAssemblerTester<double> m(MachineType::Uint64());
+  m.Return(m.RoundUint64ToFloat64(m.Parameter(0)));
+
+  for (size_t i = 0; i < arraysize(values); i++) {
+    CHECK_EQ(bit_cast<double>(values[i].expected), m.Call(values[i].input));
+  }
+}
+
+
+TEST(RunRoundUint64ToFloat32) {
+  struct {
+    uint64_t input;
+    uint32_t expected;
+  } values[] = {{0x0, 0x0},
+                {0x1, 0x3f800000},
+                {0xffffffff, 0x4f800000},
+                {0x1b09788b, 0x4dd84bc4},
+                {0x4c5fce8, 0x4c98bf9d},
+                {0xcc0de5bf, 0x4f4c0de6},
+                {0x2, 0x40000000},
+                {0x3, 0x40400000},
+                {0x4, 0x40800000},
+                {0x5, 0x40a00000},
+                {0x8, 0x41000000},
+                {0x9, 0x41100000},
+                {0xffffffffffffffff, 0x5f800000},
+                {0xfffffffffffffffe, 0x5f800000},
+                {0xfffffffffffffffd, 0x5f800000},
+                {0x0, 0x0},
+                {0x100000000, 0x4f800000},
+                {0xffffffff00000000, 0x5f800000},
+                {0x1b09788b00000000, 0x5dd84bc4},
+                {0x4c5fce800000000, 0x5c98bf9d},
+                {0xcc0de5bf00000000, 0x5f4c0de6},
+                {0x200000000, 0x50000000},
+                {0x300000000, 0x50400000},
+                {0x400000000, 0x50800000},
+                {0x500000000, 0x50a00000},
+                {0x800000000, 0x51000000},
+                {0x900000000, 0x51100000},
+                {0x273a798e187937a3, 0x5e1ce9e6},
+                {0xece3af835495a16b, 0x5f6ce3b0},
+                {0xb668ecc11223344, 0x5d3668ed},
+                {0x9e, 0x431e0000},
+                {0x43, 0x42860000},
+                {0xaf73, 0x472f7300},
+                {0x116b, 0x458b5800},
+                {0x658ecc, 0x4acb1d98},
+                {0x2b3b4c, 0x4a2ced30},
+                {0x88776655, 0x4f087766},
+                {0x70000000, 0x4ee00000},
+                {0x7200000, 0x4ce40000},
+                {0x7fffffff, 0x4f000000},
+                {0x56123761, 0x4eac246f},
+                {0x7fffff00, 0x4efffffe},
+                {0x761c4761eeeeeeee, 0x5eec388f},
+                {0x80000000eeeeeeee, 0x5f000000},
+                {0x88888888dddddddd, 0x5f088889},
+                {0xa0000000dddddddd, 0x5f200000},
+                {0xddddddddaaaaaaaa, 0x5f5dddde},
+                {0xe0000000aaaaaaaa, 0x5f600000},
+                {0xeeeeeeeeeeeeeeee, 0x5f6eeeef},
+                {0xfffffffdeeeeeeee, 0x5f800000},
+                {0xf0000000dddddddd, 0x5f700000},
+                {0x7fffffdddddddd, 0x5b000000},
+                {0x3fffffaaaaaaaa, 0x5a7fffff},
+                {0x1fffffaaaaaaaa, 0x59fffffd},
+                {0xfffff, 0x497ffff0},
+                {0x7ffff, 0x48ffffe0},
+                {0x3ffff, 0x487fffc0},
+                {0x1ffff, 0x47ffff80},
+                {0xffff, 0x477fff00},
+                {0x7fff, 0x46fffe00},
+                {0x3fff, 0x467ffc00},
+                {0x1fff, 0x45fff800},
+                {0xfff, 0x457ff000},
+                {0x7ff, 0x44ffe000},
+                {0x3ff, 0x447fc000},
+                {0x1ff, 0x43ff8000},
+                {0x3fffffffffff, 0x56800000},
+                {0x1fffffffffff, 0x56000000},
+                {0xfffffffffff, 0x55800000},
+                {0x7ffffffffff, 0x55000000},
+                {0x3ffffffffff, 0x54800000},
+                {0x1ffffffffff, 0x54000000},
+                {0x8000008000000000, 0x5f000000},
+                {0x8000008000000001, 0x5f000001},
+                {0x8000000000000400, 0x5f000000},
+                {0x8000000000000401, 0x5f000000}};
+
+  BufferedRawMachineAssemblerTester<float> m(MachineType::Uint64());
+  m.Return(m.RoundUint64ToFloat32(m.Parameter(0)));
+
+  for (size_t i = 0; i < arraysize(values); i++) {
+    CHECK_EQ(bit_cast<float>(values[i].expected), m.Call(values[i].input));
+  }
+}
+
+
+#endif
+
+
+TEST(RunBitcastFloat32ToInt32) {
+  float input = 32.25;
+  RawMachineAssemblerTester<int32_t> m;
+  m.Return(m.BitcastFloat32ToInt32(
+      m.LoadFromPointer(&input, MachineType::Float32())));
+  FOR_FLOAT32_INPUTS(i) {
+    input = *i;
+    int32_t expected = bit_cast<int32_t>(input);
+    CHECK_EQ(expected, m.Call());
+  }
+}
+
+
+TEST(RunBitcastInt32ToFloat32) {
+  int32_t input = 1;
+  float output = 0.0;
+  RawMachineAssemblerTester<int32_t> m;
+  m.StoreToPointer(
+      &output, MachineRepresentation::kFloat32,
+      m.BitcastInt32ToFloat32(m.LoadFromPointer(&input, MachineType::Int32())));
+  m.Return(m.Int32Constant(11));
+  FOR_INT32_INPUTS(i) {
+    input = *i;
+    CHECK_EQ(11, m.Call());
+    float expected = bit_cast<float>(input);
+    CHECK_EQ(bit_cast<int32_t>(expected), bit_cast<int32_t>(output));
+  }
+}
+
+
+TEST(RunComputedCodeObject) {
+  GraphBuilderTester<int32_t> a;
+  a.Return(a.Int32Constant(33));
+  a.End();
+  Handle<Code> code_a = a.GetCode();
+
+  GraphBuilderTester<int32_t> b;
+  b.Return(b.Int32Constant(44));
+  b.End();
+  Handle<Code> code_b = b.GetCode();
+
+  RawMachineAssemblerTester<int32_t> r(MachineType::Int32());
+  RawMachineLabel tlabel;
+  RawMachineLabel flabel;
+  RawMachineLabel merge;
+  r.Branch(r.Parameter(0), &tlabel, &flabel);
+  r.Bind(&tlabel);
+  Node* fa = r.HeapConstant(code_a);
+  r.Goto(&merge);
+  r.Bind(&flabel);
+  Node* fb = r.HeapConstant(code_b);
+  r.Goto(&merge);
+  r.Bind(&merge);
+  Node* phi = r.Phi(MachineRepresentation::kWord32, fa, fb);
+
+  // TODO(titzer): all this descriptor hackery is just to call the above
+  // functions as code objects instead of direct addresses.
+  CSignature0<int32_t> sig;
+  CallDescriptor* c = Linkage::GetSimplifiedCDescriptor(r.zone(), &sig);
+  LinkageLocation ret[] = {c->GetReturnLocation(0)};
+  Signature<LinkageLocation> loc(1, 0, ret);
+  CallDescriptor* desc = new (r.zone()) CallDescriptor(  // --
+      CallDescriptor::kCallCodeObject,                   // kind
+      MachineType::AnyTagged(),                          // target_type
+      c->GetInputLocation(0),                            // target_loc
+      &sig,                                              // machine_sig
+      &loc,                                              // location_sig
+      0,                                                 // stack count
+      Operator::kNoProperties,                           // properties
+      c->CalleeSavedRegisters(),                         // callee saved
+      c->CalleeSavedFPRegisters(),                       // callee saved FP
+      CallDescriptor::kNoFlags,                          // flags
+      "c-call-as-code");
+  Node* call = r.AddNode(r.common()->Call(desc), phi);
+  r.Return(call);
+
+  CHECK_EQ(33, r.Call(1));
+  CHECK_EQ(44, r.Call(0));
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/test/cctest/compiler/test-run-native-calls.cc b/test/cctest/compiler/test-run-native-calls.cc
new file mode 100644
index 0000000..791b0d7
--- /dev/null
+++ b/test/cctest/compiler/test-run-native-calls.cc
@@ -0,0 +1,1162 @@
+// Copyright 2015 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/assembler.h"
+#include "src/codegen.h"
+#include "src/compiler/linkage.h"
+#include "src/compiler/raw-machine-assembler.h"
+#include "src/machine-type.h"
+#include "src/register-configuration.h"
+
+#include "test/cctest/cctest.h"
+#include "test/cctest/compiler/codegen-tester.h"
+#include "test/cctest/compiler/graph-builder-tester.h"
+#include "test/cctest/compiler/value-helper.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+namespace {
+typedef float float32;
+typedef double float64;
+
+// Picks a representative pair of integers from the given range.
+// If there are less than {max_pairs} possible pairs, do them all, otherwise try
+// to select a representative set.
+class Pairs {
+ public:
+  Pairs(int max_pairs, int range, const int* codes)
+      : range_(range),
+        codes_(codes),
+        max_pairs_(std::min(max_pairs, range_ * range_)),
+        counter_(0) {}
+
+  bool More() { return counter_ < max_pairs_; }
+
+  void Next(int* r0, int* r1, bool same_is_ok) {
+    do {
+      // Find the next pair.
+      if (exhaustive()) {
+        *r0 = codes_[counter_ % range_];
+        *r1 = codes_[counter_ / range_];
+      } else {
+        // Try each integer at least once for both r0 and r1.
+        int index = counter_ / 2;
+        if (counter_ & 1) {
+          *r0 = codes_[index % range_];
+          *r1 = codes_[index / range_];
+        } else {
+          *r1 = codes_[index % range_];
+          *r0 = codes_[index / range_];
+        }
+      }
+      counter_++;
+      if ((same_is_ok) || (*r0 != *r1)) break;
+      if (counter_ == max_pairs_) {
+        // For the last hurrah, reg#0 with reg#n-1
+        *r0 = codes_[0];
+        *r1 = codes_[range_ - 1];
+        break;
+      }
+    } while (true);
+  }
+
+ private:
+  int range_;
+  const int* codes_;
+  int max_pairs_;
+  int counter_;
+  bool exhaustive() { return max_pairs_ == (range_ * range_); }
+};
+
+
+// Pairs of general purpose registers.
+class RegisterPairs : public Pairs {
+ public:
+  RegisterPairs()
+      : Pairs(
+            100,
+            RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN)
+                ->num_allocatable_general_registers(),
+            RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN)
+                ->allocatable_general_codes()) {}
+};
+
+
+// Pairs of double registers.
+class Float32RegisterPairs : public Pairs {
+ public:
+  Float32RegisterPairs()
+      : Pairs(
+            100,
+            RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN)
+                ->num_allocatable_aliased_double_registers(),
+            RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN)
+                ->allocatable_double_codes()) {}
+};
+
+
+// Pairs of double registers.
+class Float64RegisterPairs : public Pairs {
+ public:
+  Float64RegisterPairs()
+      : Pairs(
+            100,
+            RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN)
+                ->num_allocatable_aliased_double_registers(),
+            RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN)
+                ->allocatable_double_codes()) {}
+};
+
+
+// Helper for allocating either an GP or FP reg, or the next stack slot.
+struct Allocator {
+  Allocator(int* gp, int gpc, int* fp, int fpc)
+      : gp_count(gpc),
+        gp_offset(0),
+        gp_regs(gp),
+        fp_count(fpc),
+        fp_offset(0),
+        fp_regs(fp),
+        stack_offset(0) {}
+
+  int gp_count;
+  int gp_offset;
+  int* gp_regs;
+
+  int fp_count;
+  int fp_offset;
+  int* fp_regs;
+
+  int stack_offset;
+
+  LinkageLocation Next(MachineType type) {
+    if (IsFloatingPoint(type.representation())) {
+      // Allocate a floating point register/stack location.
+      if (fp_offset < fp_count) {
+        return LinkageLocation::ForRegister(fp_regs[fp_offset++]);
+      } else {
+        int offset = -1 - stack_offset;
+        stack_offset += StackWords(type);
+        return LinkageLocation::ForCallerFrameSlot(offset);
+      }
+    } else {
+      // Allocate a general purpose register/stack location.
+      if (gp_offset < gp_count) {
+        return LinkageLocation::ForRegister(gp_regs[gp_offset++]);
+      } else {
+        int offset = -1 - stack_offset;
+        stack_offset += StackWords(type);
+        return LinkageLocation::ForCallerFrameSlot(offset);
+      }
+    }
+  }
+  int StackWords(MachineType type) {
+    // TODO(titzer): hack. float32 occupies 8 bytes on stack.
+    int size = IsFloatingPoint(type.representation())
+                   ? kDoubleSize
+                   : (1 << ElementSizeLog2Of(type.representation()));
+    return size <= kPointerSize ? 1 : size / kPointerSize;
+  }
+  void Reset() {
+    fp_offset = 0;
+    gp_offset = 0;
+    stack_offset = 0;
+  }
+};
+
+
+class RegisterConfig {
+ public:
+  RegisterConfig(Allocator& p, Allocator& r) : params(p), rets(r) {}
+
+  CallDescriptor* Create(Zone* zone, MachineSignature* msig) {
+    rets.Reset();
+    params.Reset();
+
+    LocationSignature::Builder locations(zone, msig->return_count(),
+                                         msig->parameter_count());
+    // Add return location(s).
+    const int return_count = static_cast<int>(locations.return_count_);
+    for (int i = 0; i < return_count; i++) {
+      locations.AddReturn(rets.Next(msig->GetReturn(i)));
+    }
+
+    // Add register and/or stack parameter(s).
+    const int parameter_count = static_cast<int>(msig->parameter_count());
+    for (int i = 0; i < parameter_count; i++) {
+      locations.AddParam(params.Next(msig->GetParam(i)));
+    }
+
+    const RegList kCalleeSaveRegisters = 0;
+    const RegList kCalleeSaveFPRegisters = 0;
+
+    MachineType target_type = MachineType::AnyTagged();
+    LinkageLocation target_loc = LinkageLocation::ForAnyRegister();
+    int stack_param_count = params.stack_offset;
+    return new (zone) CallDescriptor(       // --
+        CallDescriptor::kCallCodeObject,    // kind
+        target_type,                        // target MachineType
+        target_loc,                         // target location
+        msig,                               // machine_sig
+        locations.Build(),                  // location_sig
+        stack_param_count,                  // stack_parameter_count
+        compiler::Operator::kNoProperties,  // properties
+        kCalleeSaveRegisters,               // callee-saved registers
+        kCalleeSaveFPRegisters,             // callee-saved fp regs
+        CallDescriptor::kUseNativeStack,    // flags
+        "c-call");
+  }
+
+ private:
+  Allocator& params;
+  Allocator& rets;
+};
+
+const int kMaxParamCount = 64;
+
+MachineType kIntTypes[kMaxParamCount + 1] = {
+    MachineType::Int32(), MachineType::Int32(), MachineType::Int32(),
+    MachineType::Int32(), MachineType::Int32(), MachineType::Int32(),
+    MachineType::Int32(), MachineType::Int32(), MachineType::Int32(),
+    MachineType::Int32(), MachineType::Int32(), MachineType::Int32(),
+    MachineType::Int32(), MachineType::Int32(), MachineType::Int32(),
+    MachineType::Int32(), MachineType::Int32(), MachineType::Int32(),
+    MachineType::Int32(), MachineType::Int32(), MachineType::Int32(),
+    MachineType::Int32(), MachineType::Int32(), MachineType::Int32(),
+    MachineType::Int32(), MachineType::Int32(), MachineType::Int32(),
+    MachineType::Int32(), MachineType::Int32(), MachineType::Int32(),
+    MachineType::Int32(), MachineType::Int32(), MachineType::Int32(),
+    MachineType::Int32(), MachineType::Int32(), MachineType::Int32(),
+    MachineType::Int32(), MachineType::Int32(), MachineType::Int32(),
+    MachineType::Int32(), MachineType::Int32(), MachineType::Int32(),
+    MachineType::Int32(), MachineType::Int32(), MachineType::Int32(),
+    MachineType::Int32(), MachineType::Int32(), MachineType::Int32(),
+    MachineType::Int32(), MachineType::Int32(), MachineType::Int32(),
+    MachineType::Int32(), MachineType::Int32(), MachineType::Int32(),
+    MachineType::Int32(), MachineType::Int32(), MachineType::Int32(),
+    MachineType::Int32(), MachineType::Int32(), MachineType::Int32(),
+    MachineType::Int32(), MachineType::Int32(), MachineType::Int32(),
+    MachineType::Int32(), MachineType::Int32()};
+
+
+// For making uniform int32 signatures shorter.
+class Int32Signature : public MachineSignature {
+ public:
+  explicit Int32Signature(int param_count)
+      : MachineSignature(1, param_count, kIntTypes) {
+    CHECK(param_count <= kMaxParamCount);
+  }
+};
+
+
+Handle<Code> CompileGraph(const char* name, CallDescriptor* desc, Graph* graph,
+                          Schedule* schedule = nullptr) {
+  Isolate* isolate = CcTest::InitIsolateOnce();
+  CompilationInfo info("testing", isolate, graph->zone());
+  Handle<Code> code =
+      Pipeline::GenerateCodeForTesting(&info, desc, graph, schedule);
+  CHECK(!code.is_null());
+#ifdef ENABLE_DISASSEMBLER
+  if (FLAG_print_opt_code) {
+    OFStream os(stdout);
+    code->Disassemble(name, os);
+  }
+#endif
+  return code;
+}
+
+
+Handle<Code> WrapWithCFunction(Handle<Code> inner, CallDescriptor* desc) {
+  Zone zone;
+  MachineSignature* msig =
+      const_cast<MachineSignature*>(desc->GetMachineSignature());
+  int param_count = static_cast<int>(msig->parameter_count());
+  GraphAndBuilders caller(&zone);
+  {
+    GraphAndBuilders& b = caller;
+    Node* start = b.graph()->NewNode(b.common()->Start(param_count + 3));
+    b.graph()->SetStart(start);
+    Node* target = b.graph()->NewNode(b.common()->HeapConstant(inner));
+
+    // Add arguments to the call.
+    Node** args = zone.NewArray<Node*>(param_count + 3);
+    int index = 0;
+    args[index++] = target;
+    for (int i = 0; i < param_count; i++) {
+      args[index] = b.graph()->NewNode(b.common()->Parameter(i), start);
+      index++;
+    }
+    args[index++] = start;  // effect.
+    args[index++] = start;  // control.
+
+    // Build the call and return nodes.
+    Node* call =
+        b.graph()->NewNode(b.common()->Call(desc), param_count + 3, args);
+    Node* ret = b.graph()->NewNode(b.common()->Return(), call, call, start);
+    b.graph()->SetEnd(ret);
+  }
+
+  CallDescriptor* cdesc = Linkage::GetSimplifiedCDescriptor(&zone, msig);
+
+  return CompileGraph("wrapper", cdesc, caller.graph());
+}
+
+
+template <typename CType>
+class ArgsBuffer {
+ public:
+  static const int kMaxParamCount = 64;
+
+  explicit ArgsBuffer(int count, int seed = 1) : count_(count), seed_(seed) {
+    // initialize the buffer with "seed 0"
+    seed_ = 0;
+    Mutate();
+    seed_ = seed;
+  }
+
+  class Sig : public MachineSignature {
+   public:
+    explicit Sig(int param_count)
+        : MachineSignature(1, param_count, MachTypes()) {
+      CHECK(param_count <= kMaxParamCount);
+    }
+  };
+
+  static MachineType* MachTypes() {
+    MachineType t = MachineTypeForC<CType>();
+    static MachineType kTypes[kMaxParamCount + 1] = {
+        t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t,
+        t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t,
+        t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t};
+    return kTypes;
+  }
+
+  Node* MakeConstant(RawMachineAssembler& raw, int32_t value) {
+    return raw.Int32Constant(value);
+  }
+
+  Node* MakeConstant(RawMachineAssembler& raw, int64_t value) {
+    return raw.Int64Constant(value);
+  }
+
+  Node* MakeConstant(RawMachineAssembler& raw, float32 value) {
+    return raw.Float32Constant(value);
+  }
+
+  Node* MakeConstant(RawMachineAssembler& raw, float64 value) {
+    return raw.Float64Constant(value);
+  }
+
+  Node* LoadInput(RawMachineAssembler& raw, Node* base, int index) {
+    Node* offset = raw.Int32Constant(index * sizeof(CType));
+    return raw.Load(MachineTypeForC<CType>(), base, offset);
+  }
+
+  Node* StoreOutput(RawMachineAssembler& raw, Node* value) {
+    Node* base = raw.PointerConstant(&output);
+    Node* offset = raw.Int32Constant(0);
+    return raw.Store(MachineTypeForC<CType>().representation(), base, offset,
+                     value, kNoWriteBarrier);
+  }
+
+  // Computes the next set of inputs by updating the {input} array.
+  void Mutate();
+
+  void Reset() { memset(input, 0, sizeof(input)); }
+
+  int count_;
+  int seed_;
+  CType input[kMaxParamCount];
+  CType output;
+};
+
+
+template <>
+void ArgsBuffer<int32_t>::Mutate() {
+  uint32_t base = 1111111111u * seed_;
+  for (int j = 0; j < count_ && j < kMaxParamCount; j++) {
+    input[j] = static_cast<int32_t>(256 + base + j + seed_ * 13);
+  }
+  output = -1;
+  seed_++;
+}
+
+
+template <>
+void ArgsBuffer<int64_t>::Mutate() {
+  uint64_t base = 11111111111111111ull * seed_;
+  for (int j = 0; j < count_ && j < kMaxParamCount; j++) {
+    input[j] = static_cast<int64_t>(256 + base + j + seed_ * 13);
+  }
+  output = -1;
+  seed_++;
+}
+
+
+template <>
+void ArgsBuffer<float32>::Mutate() {
+  float64 base = -33.25 * seed_;
+  for (int j = 0; j < count_ && j < kMaxParamCount; j++) {
+    input[j] = 256 + base + j + seed_ * 13;
+  }
+  output = std::numeric_limits<float32>::quiet_NaN();
+  seed_++;
+}
+
+
+template <>
+void ArgsBuffer<float64>::Mutate() {
+  float64 base = -111.25 * seed_;
+  for (int j = 0; j < count_ && j < kMaxParamCount; j++) {
+    input[j] = 256 + base + j + seed_ * 13;
+  }
+  output = std::numeric_limits<float64>::quiet_NaN();
+  seed_++;
+}
+
+
+int ParamCount(CallDescriptor* desc) {
+  return static_cast<int>(desc->GetMachineSignature()->parameter_count());
+}
+
+
+template <typename CType>
+class Computer {
+ public:
+  static void Run(CallDescriptor* desc,
+                  void (*build)(CallDescriptor*, RawMachineAssembler&),
+                  CType (*compute)(CallDescriptor*, CType* inputs),
+                  int seed = 1) {
+    int num_params = ParamCount(desc);
+    CHECK_LE(num_params, kMaxParamCount);
+    Isolate* isolate = CcTest::InitIsolateOnce();
+    HandleScope scope(isolate);
+    Handle<Code> inner = Handle<Code>::null();
+    {
+      // Build the graph for the computation.
+      Zone zone;
+      Graph graph(&zone);
+      RawMachineAssembler raw(isolate, &graph, desc);
+      build(desc, raw);
+      inner = CompileGraph("Compute", desc, &graph, raw.Export());
+    }
+
+    CSignature0<int32_t> csig;
+    ArgsBuffer<CType> io(num_params, seed);
+
+    {
+      // constant mode.
+      Handle<Code> wrapper = Handle<Code>::null();
+      {
+        // Wrap the above code with a callable function that passes constants.
+        Zone zone;
+        Graph graph(&zone);
+        CallDescriptor* cdesc = Linkage::GetSimplifiedCDescriptor(&zone, &csig);
+        RawMachineAssembler raw(isolate, &graph, cdesc);
+        Node* target = raw.HeapConstant(inner);
+        Node** args = zone.NewArray<Node*>(num_params);
+        for (int i = 0; i < num_params; i++) {
+          args[i] = io.MakeConstant(raw, io.input[i]);
+        }
+
+        Node* call = raw.CallN(desc, target, args);
+        Node* store = io.StoreOutput(raw, call);
+        USE(store);
+        raw.Return(raw.Int32Constant(seed));
+        wrapper =
+            CompileGraph("Compute-wrapper-const", cdesc, &graph, raw.Export());
+      }
+
+      CodeRunner<int32_t> runnable(isolate, wrapper, &csig);
+
+      // Run the code, checking it against the reference.
+      CType expected = compute(desc, io.input);
+      int32_t check_seed = runnable.Call();
+      CHECK_EQ(seed, check_seed);
+      CHECK_EQ(expected, io.output);
+    }
+
+    {
+      // buffer mode.
+      Handle<Code> wrapper = Handle<Code>::null();
+      {
+        // Wrap the above code with a callable function that loads from {input}.
+        Zone zone;
+        Graph graph(&zone);
+        CallDescriptor* cdesc = Linkage::GetSimplifiedCDescriptor(&zone, &csig);
+        RawMachineAssembler raw(isolate, &graph, cdesc);
+        Node* base = raw.PointerConstant(io.input);
+        Node* target = raw.HeapConstant(inner);
+        Node** args = zone.NewArray<Node*>(kMaxParamCount);
+        for (int i = 0; i < num_params; i++) {
+          args[i] = io.LoadInput(raw, base, i);
+        }
+
+        Node* call = raw.CallN(desc, target, args);
+        Node* store = io.StoreOutput(raw, call);
+        USE(store);
+        raw.Return(raw.Int32Constant(seed));
+        wrapper = CompileGraph("Compute-wrapper", cdesc, &graph, raw.Export());
+      }
+
+      CodeRunner<int32_t> runnable(isolate, wrapper, &csig);
+
+      // Run the code, checking it against the reference.
+      for (int i = 0; i < 5; i++) {
+        CType expected = compute(desc, io.input);
+        int32_t check_seed = runnable.Call();
+        CHECK_EQ(seed, check_seed);
+        CHECK_EQ(expected, io.output);
+        io.Mutate();
+      }
+    }
+  }
+};
+
+}  // namespace
+
+
+static void TestInt32Sub(CallDescriptor* desc) {
+  Isolate* isolate = CcTest::InitIsolateOnce();
+  HandleScope scope(isolate);
+  Zone zone;
+  GraphAndBuilders inner(&zone);
+  {
+    // Build the add function.
+    GraphAndBuilders& b = inner;
+    Node* start = b.graph()->NewNode(b.common()->Start(5));
+    b.graph()->SetStart(start);
+    Node* p0 = b.graph()->NewNode(b.common()->Parameter(0), start);
+    Node* p1 = b.graph()->NewNode(b.common()->Parameter(1), start);
+    Node* add = b.graph()->NewNode(b.machine()->Int32Sub(), p0, p1);
+    Node* ret = b.graph()->NewNode(b.common()->Return(), add, start, start);
+    b.graph()->SetEnd(ret);
+  }
+
+  Handle<Code> inner_code = CompileGraph("Int32Sub", desc, inner.graph());
+  Handle<Code> wrapper = WrapWithCFunction(inner_code, desc);
+  MachineSignature* msig =
+      const_cast<MachineSignature*>(desc->GetMachineSignature());
+  CodeRunner<int32_t> runnable(isolate, wrapper,
+                               CSignature::FromMachine(&zone, msig));
+
+  FOR_INT32_INPUTS(i) {
+    FOR_INT32_INPUTS(j) {
+      int32_t expected = static_cast<int32_t>(static_cast<uint32_t>(*i) -
+                                              static_cast<uint32_t>(*j));
+      int32_t result = runnable.Call(*i, *j);
+      CHECK_EQ(expected, result);
+    }
+  }
+}
+
+
+static void CopyTwentyInt32(CallDescriptor* desc) {
+  const int kNumParams = 20;
+  int32_t input[kNumParams];
+  int32_t output[kNumParams];
+  Isolate* isolate = CcTest::InitIsolateOnce();
+  HandleScope scope(isolate);
+  Handle<Code> inner = Handle<Code>::null();
+  {
+    // Writes all parameters into the output buffer.
+    Zone zone;
+    Graph graph(&zone);
+    RawMachineAssembler raw(isolate, &graph, desc);
+    Node* base = raw.PointerConstant(output);
+    for (int i = 0; i < kNumParams; i++) {
+      Node* offset = raw.Int32Constant(i * sizeof(int32_t));
+      raw.Store(MachineRepresentation::kWord32, base, offset, raw.Parameter(i),
+                kNoWriteBarrier);
+    }
+    raw.Return(raw.Int32Constant(42));
+    inner = CompileGraph("CopyTwentyInt32", desc, &graph, raw.Export());
+  }
+
+  CSignature0<int32_t> csig;
+  Handle<Code> wrapper = Handle<Code>::null();
+  {
+    // Loads parameters from the input buffer and calls the above code.
+    Zone zone;
+    Graph graph(&zone);
+    CallDescriptor* cdesc = Linkage::GetSimplifiedCDescriptor(&zone, &csig);
+    RawMachineAssembler raw(isolate, &graph, cdesc);
+    Node* base = raw.PointerConstant(input);
+    Node* target = raw.HeapConstant(inner);
+    Node** args = zone.NewArray<Node*>(kNumParams);
+    for (int i = 0; i < kNumParams; i++) {
+      Node* offset = raw.Int32Constant(i * sizeof(int32_t));
+      args[i] = raw.Load(MachineType::Int32(), base, offset);
+    }
+
+    Node* call = raw.CallN(desc, target, args);
+    raw.Return(call);
+    wrapper =
+        CompileGraph("CopyTwentyInt32-wrapper", cdesc, &graph, raw.Export());
+  }
+
+  CodeRunner<int32_t> runnable(isolate, wrapper, &csig);
+
+  // Run the code, checking it correctly implements the memcpy.
+  for (int i = 0; i < 5; i++) {
+    uint32_t base = 1111111111u * i;
+    for (int j = 0; j < kNumParams; j++) {
+      input[j] = static_cast<int32_t>(base + 13 * j);
+    }
+
+    memset(output, 0, sizeof(output));
+    CHECK_EQ(42, runnable.Call());
+
+    for (int j = 0; j < kNumParams; j++) {
+      CHECK_EQ(input[j], output[j]);
+    }
+  }
+}
+
+
+static void Test_RunInt32SubWithRet(int retreg) {
+  Int32Signature sig(2);
+  Zone zone;
+  RegisterPairs pairs;
+  while (pairs.More()) {
+    int parray[2];
+    int rarray[] = {retreg};
+    pairs.Next(&parray[0], &parray[1], false);
+    Allocator params(parray, 2, nullptr, 0);
+    Allocator rets(rarray, 1, nullptr, 0);
+    RegisterConfig config(params, rets);
+    CallDescriptor* desc = config.Create(&zone, &sig);
+    TestInt32Sub(desc);
+  }
+}
+
+
+// Separate tests for parallelization.
+#define TEST_INT32_SUB_WITH_RET(x)                \
+  TEST(Run_Int32Sub_all_allocatable_pairs_##x) {  \
+    if (x < Register::kNumRegisters &&            \
+        Register::from_code(x).IsAllocatable()) { \
+      Test_RunInt32SubWithRet(x);                 \
+    }                                             \
+  }
+
+
+TEST_INT32_SUB_WITH_RET(0)
+TEST_INT32_SUB_WITH_RET(1)
+TEST_INT32_SUB_WITH_RET(2)
+TEST_INT32_SUB_WITH_RET(3)
+TEST_INT32_SUB_WITH_RET(4)
+TEST_INT32_SUB_WITH_RET(5)
+TEST_INT32_SUB_WITH_RET(6)
+TEST_INT32_SUB_WITH_RET(7)
+TEST_INT32_SUB_WITH_RET(8)
+TEST_INT32_SUB_WITH_RET(9)
+TEST_INT32_SUB_WITH_RET(10)
+TEST_INT32_SUB_WITH_RET(11)
+TEST_INT32_SUB_WITH_RET(12)
+TEST_INT32_SUB_WITH_RET(13)
+TEST_INT32_SUB_WITH_RET(14)
+TEST_INT32_SUB_WITH_RET(15)
+TEST_INT32_SUB_WITH_RET(16)
+TEST_INT32_SUB_WITH_RET(17)
+TEST_INT32_SUB_WITH_RET(18)
+TEST_INT32_SUB_WITH_RET(19)
+
+
+TEST(Run_Int32Sub_all_allocatable_single) {
+  Int32Signature sig(2);
+  RegisterPairs pairs;
+  while (pairs.More()) {
+    Zone zone;
+    int parray[1];
+    int rarray[1];
+    pairs.Next(&rarray[0], &parray[0], true);
+    Allocator params(parray, 1, nullptr, 0);
+    Allocator rets(rarray, 1, nullptr, 0);
+    RegisterConfig config(params, rets);
+    CallDescriptor* desc = config.Create(&zone, &sig);
+    TestInt32Sub(desc);
+  }
+}
+
+
+TEST(Run_CopyTwentyInt32_all_allocatable_pairs) {
+  Int32Signature sig(20);
+  RegisterPairs pairs;
+  while (pairs.More()) {
+    Zone zone;
+    int parray[2];
+    int rarray[] = {
+        RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN)
+            ->GetAllocatableGeneralCode(0)};
+    pairs.Next(&parray[0], &parray[1], false);
+    Allocator params(parray, 2, nullptr, 0);
+    Allocator rets(rarray, 1, nullptr, 0);
+    RegisterConfig config(params, rets);
+    CallDescriptor* desc = config.Create(&zone, &sig);
+    CopyTwentyInt32(desc);
+  }
+}
+
+
+template <typename CType>
+static void Run_Computation(
+    CallDescriptor* desc, void (*build)(CallDescriptor*, RawMachineAssembler&),
+    CType (*compute)(CallDescriptor*, CType* inputs), int seed = 1) {
+  Computer<CType>::Run(desc, build, compute, seed);
+}
+
+
+static uint32_t coeff[] = {1,  2,  3,  5,  7,   11,  13,  17,  19, 23, 29,
+                           31, 37, 41, 43, 47,  53,  59,  61,  67, 71, 73,
+                           79, 83, 89, 97, 101, 103, 107, 109, 113};
+
+
+static void Build_Int32_WeightedSum(CallDescriptor* desc,
+                                    RawMachineAssembler& raw) {
+  Node* result = raw.Int32Constant(0);
+  for (int i = 0; i < ParamCount(desc); i++) {
+    Node* term = raw.Int32Mul(raw.Parameter(i), raw.Int32Constant(coeff[i]));
+    result = raw.Int32Add(result, term);
+  }
+  raw.Return(result);
+}
+
+
+static int32_t Compute_Int32_WeightedSum(CallDescriptor* desc, int32_t* input) {
+  uint32_t result = 0;
+  for (int i = 0; i < ParamCount(desc); i++) {
+    result += static_cast<uint32_t>(input[i]) * coeff[i];
+  }
+  return static_cast<int32_t>(result);
+}
+
+
+static void Test_Int32_WeightedSum_of_size(int count) {
+  Int32Signature sig(count);
+  for (int p0 = 0; p0 < Register::kNumRegisters; p0++) {
+    if (Register::from_code(p0).IsAllocatable()) {
+      Zone zone;
+
+      int parray[] = {p0};
+      int rarray[] = {
+          RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN)
+              ->GetAllocatableGeneralCode(0)};
+      Allocator params(parray, 1, nullptr, 0);
+      Allocator rets(rarray, 1, nullptr, 0);
+      RegisterConfig config(params, rets);
+      CallDescriptor* desc = config.Create(&zone, &sig);
+      Run_Computation<int32_t>(desc, Build_Int32_WeightedSum,
+                               Compute_Int32_WeightedSum, 257 + count);
+    }
+  }
+}
+
+
+// Separate tests for parallelization.
+#define TEST_INT32_WEIGHTEDSUM(x) \
+  TEST(Run_Int32_WeightedSum_##x) { Test_Int32_WeightedSum_of_size(x); }
+
+
+TEST_INT32_WEIGHTEDSUM(1)
+TEST_INT32_WEIGHTEDSUM(2)
+TEST_INT32_WEIGHTEDSUM(3)
+TEST_INT32_WEIGHTEDSUM(4)
+TEST_INT32_WEIGHTEDSUM(5)
+TEST_INT32_WEIGHTEDSUM(7)
+TEST_INT32_WEIGHTEDSUM(9)
+TEST_INT32_WEIGHTEDSUM(11)
+TEST_INT32_WEIGHTEDSUM(17)
+TEST_INT32_WEIGHTEDSUM(19)
+
+
+template <int which>
+static void Build_Select(CallDescriptor* desc, RawMachineAssembler& raw) {
+  raw.Return(raw.Parameter(which));
+}
+
+
+template <typename CType, int which>
+static CType Compute_Select(CallDescriptor* desc, CType* inputs) {
+  return inputs[which];
+}
+
+
+template <typename CType, int which>
+static void RunSelect(CallDescriptor* desc) {
+  int count = ParamCount(desc);
+  if (count <= which) return;
+  Run_Computation<CType>(desc, Build_Select<which>,
+                         Compute_Select<CType, which>,
+                         1044 + which + 3 * sizeof(CType));
+}
+
+
+template <int which>
+void Test_Int32_Select() {
+  int parray[] = {
+      RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN)
+          ->GetAllocatableGeneralCode(0)};
+  int rarray[] = {
+      RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN)
+          ->GetAllocatableGeneralCode(0)};
+  Allocator params(parray, 1, nullptr, 0);
+  Allocator rets(rarray, 1, nullptr, 0);
+  RegisterConfig config(params, rets);
+
+  Zone zone;
+
+  for (int i = which + 1; i <= 64; i++) {
+    Int32Signature sig(i);
+    CallDescriptor* desc = config.Create(&zone, &sig);
+    RunSelect<int32_t, which>(desc);
+  }
+}
+
+
+// Separate tests for parallelization.
+#define TEST_INT32_SELECT(x) \
+  TEST(Run_Int32_Select_##x) { Test_Int32_Select<x>(); }
+
+
+TEST_INT32_SELECT(0)
+TEST_INT32_SELECT(1)
+TEST_INT32_SELECT(2)
+TEST_INT32_SELECT(3)
+TEST_INT32_SELECT(4)
+TEST_INT32_SELECT(5)
+TEST_INT32_SELECT(6)
+TEST_INT32_SELECT(11)
+TEST_INT32_SELECT(15)
+TEST_INT32_SELECT(19)
+TEST_INT32_SELECT(45)
+TEST_INT32_SELECT(62)
+TEST_INT32_SELECT(63)
+
+
+TEST(Int64Select_registers) {
+  if (RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN)
+          ->num_allocatable_general_registers() < 2)
+    return;
+  if (kPointerSize < 8) return;  // TODO(titzer): int64 on 32-bit platforms
+
+  int rarray[] = {
+      RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN)
+          ->GetAllocatableGeneralCode(0)};
+  ArgsBuffer<int64_t>::Sig sig(2);
+
+  RegisterPairs pairs;
+  Zone zone;
+  while (pairs.More()) {
+    int parray[2];
+    pairs.Next(&parray[0], &parray[1], false);
+    Allocator params(parray, 2, nullptr, 0);
+    Allocator rets(rarray, 1, nullptr, 0);
+    RegisterConfig config(params, rets);
+
+    CallDescriptor* desc = config.Create(&zone, &sig);
+    RunSelect<int64_t, 0>(desc);
+    RunSelect<int64_t, 1>(desc);
+  }
+}
+
+
+TEST(Float32Select_registers) {
+  if (RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN)
+          ->num_allocatable_double_registers() < 2) {
+    return;
+  }
+
+  int rarray[] = {
+      RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN)
+          ->GetAllocatableDoubleCode(0)};
+  ArgsBuffer<float32>::Sig sig(2);
+
+  Float32RegisterPairs pairs;
+  Zone zone;
+  while (pairs.More()) {
+    int parray[2];
+    pairs.Next(&parray[0], &parray[1], false);
+    Allocator params(nullptr, 0, parray, 2);
+    Allocator rets(nullptr, 0, rarray, 1);
+    RegisterConfig config(params, rets);
+
+    CallDescriptor* desc = config.Create(&zone, &sig);
+    RunSelect<float32, 0>(desc);
+    RunSelect<float32, 1>(desc);
+  }
+}
+
+
+TEST(Float64Select_registers) {
+  if (RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN)
+          ->num_allocatable_double_registers() < 2)
+    return;
+  if (RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN)
+          ->num_allocatable_general_registers() < 2)
+    return;
+  int rarray[] = {
+      RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN)
+          ->GetAllocatableDoubleCode(0)};
+  ArgsBuffer<float64>::Sig sig(2);
+
+  Float64RegisterPairs pairs;
+  Zone zone;
+  while (pairs.More()) {
+    int parray[2];
+    pairs.Next(&parray[0], &parray[1], false);
+    Allocator params(nullptr, 0, parray, 2);
+    Allocator rets(nullptr, 0, rarray, 1);
+    RegisterConfig config(params, rets);
+
+    CallDescriptor* desc = config.Create(&zone, &sig);
+    RunSelect<float64, 0>(desc);
+    RunSelect<float64, 1>(desc);
+  }
+}
+
+
+TEST(Float32Select_stack_params_return_reg) {
+  int rarray[] = {
+      RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN)
+          ->GetAllocatableDoubleCode(0)};
+  Allocator params(nullptr, 0, nullptr, 0);
+  Allocator rets(nullptr, 0, rarray, 1);
+  RegisterConfig config(params, rets);
+
+  Zone zone;
+  for (int count = 1; count < 6; count++) {
+    ArgsBuffer<float32>::Sig sig(count);
+    CallDescriptor* desc = config.Create(&zone, &sig);
+    RunSelect<float32, 0>(desc);
+    RunSelect<float32, 1>(desc);
+    RunSelect<float32, 2>(desc);
+    RunSelect<float32, 3>(desc);
+    RunSelect<float32, 4>(desc);
+    RunSelect<float32, 5>(desc);
+  }
+}
+
+
+TEST(Float64Select_stack_params_return_reg) {
+  int rarray[] = {
+      RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN)
+          ->GetAllocatableDoubleCode(0)};
+  Allocator params(nullptr, 0, nullptr, 0);
+  Allocator rets(nullptr, 0, rarray, 1);
+  RegisterConfig config(params, rets);
+
+  Zone zone;
+  for (int count = 1; count < 6; count++) {
+    ArgsBuffer<float64>::Sig sig(count);
+    CallDescriptor* desc = config.Create(&zone, &sig);
+    RunSelect<float64, 0>(desc);
+    RunSelect<float64, 1>(desc);
+    RunSelect<float64, 2>(desc);
+    RunSelect<float64, 3>(desc);
+    RunSelect<float64, 4>(desc);
+    RunSelect<float64, 5>(desc);
+  }
+}
+
+
+template <typename CType, int which>
+static void Build_Select_With_Call(CallDescriptor* desc,
+                                   RawMachineAssembler& raw) {
+  Handle<Code> inner = Handle<Code>::null();
+  int num_params = ParamCount(desc);
+  CHECK_LE(num_params, kMaxParamCount);
+  {
+    Isolate* isolate = CcTest::InitIsolateOnce();
+    // Build the actual select.
+    Zone zone;
+    Graph graph(&zone);
+    RawMachineAssembler raw(isolate, &graph, desc);
+    raw.Return(raw.Parameter(which));
+    inner = CompileGraph("Select-indirection", desc, &graph, raw.Export());
+    CHECK(!inner.is_null());
+    CHECK(inner->IsCode());
+  }
+
+  {
+    // Build a call to the function that does the select.
+    Node* target = raw.HeapConstant(inner);
+    Node** args = raw.zone()->NewArray<Node*>(num_params);
+    for (int i = 0; i < num_params; i++) {
+      args[i] = raw.Parameter(i);
+    }
+
+    Node* call = raw.CallN(desc, target, args);
+    raw.Return(call);
+  }
+}
+
+
+TEST(Float64StackParamsToStackParams) {
+  int rarray[] = {
+      RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN)
+          ->GetAllocatableDoubleCode(0)};
+  Allocator params(nullptr, 0, nullptr, 0);
+  Allocator rets(nullptr, 0, rarray, 1);
+
+  Zone zone;
+  ArgsBuffer<float64>::Sig sig(2);
+  RegisterConfig config(params, rets);
+  CallDescriptor* desc = config.Create(&zone, &sig);
+
+  Run_Computation<float64>(desc, Build_Select_With_Call<float64, 0>,
+                           Compute_Select<float64, 0>, 1098);
+
+  Run_Computation<float64>(desc, Build_Select_With_Call<float64, 1>,
+                           Compute_Select<float64, 1>, 1099);
+}
+
+
+void MixedParamTest(int start) {
+  if (RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN)
+          ->num_double_registers() < 2)
+    return;
+
+// TODO(titzer): mix in 64-bit types on all platforms when supported.
+#if V8_TARGET_ARCH_32_BIT
+  static MachineType types[] = {
+      MachineType::Int32(),   MachineType::Float32(), MachineType::Float64(),
+      MachineType::Int32(),   MachineType::Float64(), MachineType::Float32(),
+      MachineType::Float32(), MachineType::Float64(), MachineType::Int32(),
+      MachineType::Float32(), MachineType::Int32(),   MachineType::Float64(),
+      MachineType::Float64(), MachineType::Float32(), MachineType::Int32(),
+      MachineType::Float64(), MachineType::Int32(),   MachineType::Float32()};
+#else
+  static MachineType types[] = {
+      MachineType::Int32(),   MachineType::Int64(),   MachineType::Float32(),
+      MachineType::Float64(), MachineType::Int32(),   MachineType::Float64(),
+      MachineType::Float32(), MachineType::Int64(),   MachineType::Int64(),
+      MachineType::Float32(), MachineType::Float32(), MachineType::Int32(),
+      MachineType::Float64(), MachineType::Float64(), MachineType::Int64(),
+      MachineType::Int32(),   MachineType::Float64(), MachineType::Int32(),
+      MachineType::Float32()};
+#endif
+
+  Isolate* isolate = CcTest::InitIsolateOnce();
+
+  // Build machine signature
+  MachineType* params = &types[start];
+  const int num_params = static_cast<int>(arraysize(types) - start);
+
+  // Build call descriptor
+  int parray_gp[] = {
+      RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN)
+          ->GetAllocatableGeneralCode(0),
+      RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN)
+          ->GetAllocatableGeneralCode(1)};
+  int rarray_gp[] = {
+      RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN)
+          ->GetAllocatableGeneralCode(0)};
+  int parray_fp[] = {
+      RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN)
+          ->GetAllocatableDoubleCode(0),
+      RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN)
+          ->GetAllocatableDoubleCode(1)};
+  int rarray_fp[] = {
+      RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN)
+          ->GetAllocatableDoubleCode(0)};
+  Allocator palloc(parray_gp, 2, parray_fp, 2);
+  Allocator ralloc(rarray_gp, 1, rarray_fp, 1);
+  RegisterConfig config(palloc, ralloc);
+
+  for (int which = 0; which < num_params; which++) {
+    Zone zone;
+    HandleScope scope(isolate);
+    MachineSignature::Builder builder(&zone, 1, num_params);
+    builder.AddReturn(params[which]);
+    for (int j = 0; j < num_params; j++) builder.AddParam(params[j]);
+    MachineSignature* sig = builder.Build();
+    CallDescriptor* desc = config.Create(&zone, sig);
+
+    Handle<Code> select;
+    {
+      // build the select.
+      Zone zone;
+      Graph graph(&zone);
+      RawMachineAssembler raw(isolate, &graph, desc);
+      raw.Return(raw.Parameter(which));
+      select = CompileGraph("Compute", desc, &graph, raw.Export());
+    }
+
+    {
+      // call the select.
+      Handle<Code> wrapper = Handle<Code>::null();
+      int32_t expected_ret;
+      char bytes[kDoubleSize];
+      V8_ALIGNED(8) char output[kDoubleSize];
+      int expected_size = 0;
+      CSignature0<int32_t> csig;
+      {
+        // Wrap the select code with a callable function that passes constants.
+        Zone zone;
+        Graph graph(&zone);
+        CallDescriptor* cdesc = Linkage::GetSimplifiedCDescriptor(&zone, &csig);
+        RawMachineAssembler raw(isolate, &graph, cdesc);
+        Node* target = raw.HeapConstant(select);
+        Node** args = zone.NewArray<Node*>(num_params);
+        int64_t constant = 0x0102030405060708;
+        for (int i = 0; i < num_params; i++) {
+          MachineType param_type = sig->GetParam(i);
+          Node* konst = nullptr;
+          if (param_type == MachineType::Int32()) {
+            int32_t value[] = {static_cast<int32_t>(constant)};
+            konst = raw.Int32Constant(value[0]);
+            if (i == which) memcpy(bytes, value, expected_size = 4);
+          }
+          if (param_type == MachineType::Int64()) {
+            int64_t value[] = {static_cast<int64_t>(constant)};
+            konst = raw.Int64Constant(value[0]);
+            if (i == which) memcpy(bytes, value, expected_size = 8);
+          }
+          if (param_type == MachineType::Float32()) {
+            float32 value[] = {static_cast<float32>(constant)};
+            konst = raw.Float32Constant(value[0]);
+            if (i == which) memcpy(bytes, value, expected_size = 4);
+          }
+          if (param_type == MachineType::Float64()) {
+            float64 value[] = {static_cast<float64>(constant)};
+            konst = raw.Float64Constant(value[0]);
+            if (i == which) memcpy(bytes, value, expected_size = 8);
+          }
+          CHECK_NOT_NULL(konst);
+
+          args[i] = konst;
+          constant += 0x1010101010101010;
+        }
+
+        Node* call = raw.CallN(desc, target, args);
+        Node* store =
+            raw.StoreToPointer(output, sig->GetReturn().representation(), call);
+        USE(store);
+        expected_ret = static_cast<int32_t>(constant);
+        raw.Return(raw.Int32Constant(expected_ret));
+        wrapper = CompileGraph("Select-mixed-wrapper-const", cdesc, &graph,
+                               raw.Export());
+      }
+
+      CodeRunner<int32_t> runnable(isolate, wrapper, &csig);
+      CHECK_EQ(expected_ret, runnable.Call());
+      for (int i = 0; i < expected_size; i++) {
+        CHECK_EQ(static_cast<int>(bytes[i]), static_cast<int>(output[i]));
+      }
+    }
+  }
+}
+
+
+TEST(MixedParams_0) { MixedParamTest(0); }
+TEST(MixedParams_1) { MixedParamTest(1); }
+TEST(MixedParams_2) { MixedParamTest(2); }
+TEST(MixedParams_3) { MixedParamTest(3); }
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/test/cctest/compiler/test-run-properties.cc b/test/cctest/compiler/test-run-properties.cc
index d4442f7..3c42102 100644
--- a/test/cctest/compiler/test-run-properties.cc
+++ b/test/cctest/compiler/test-run-properties.cc
@@ -2,12 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "src/v8.h"
-
 #include "test/cctest/compiler/function-tester.h"
 
-using namespace v8::internal;
-using namespace v8::internal::compiler;
+namespace v8 {
+namespace internal {
+namespace compiler {
 
 template <typename U>
 static void TypedArrayLoadHelper(const char* array_type) {
@@ -21,16 +20,15 @@
     values_builder.AddFormatted("a[%d] = 0x%08x;", i, kValues[i]);
   }
 
-  // Note that below source creates two different typed arrays with distinct
-  // elements kind to get coverage for both access patterns:
-  // - IsFixedTypedArrayElementsKind(x)
-  // - IsExternalArrayElementsKind(y)
+  // Note that below source creates two different typed arrays with the same
+  // elements kind to get coverage for both (on heap / with external backing
+  // store) access patterns.
   const char* source =
       "(function(a) {"
       "  var x = (a = new %sArray(%d)); %s;"
       "  var y = (a = new %sArray(%d)); %s; %%TypedArrayGetBuffer(y);"
       "  if (!%%HasFixed%sElements(x)) %%AbortJS('x');"
-      "  if (!%%HasExternal%sElements(y)) %%AbortJS('y');"
+      "  if (!%%HasFixed%sElements(y)) %%AbortJS('y');"
       "  function f(a,b) {"
       "    a = a | 0; b = b | 0;"
       "    return x[a] + y[b];"
@@ -42,9 +40,9 @@
            values_buffer.start(), array_type, arraysize(kValues),
            values_buffer.start(), array_type, array_type);
 
-  FunctionTester T(
-      source_buffer.start(),
-      CompilationInfo::kContextSpecializing | CompilationInfo::kTypingEnabled);
+  FunctionTester T(source_buffer.start(),
+                   CompilationInfo::kFunctionContextSpecializing |
+                       CompilationInfo::kTypingEnabled);
   for (size_t i = 0; i < arraysize(kValues); ++i) {
     for (size_t j = 0; j < arraysize(kValues); ++j) {
       volatile U value_a = static_cast<U>(kValues[i]);
@@ -84,16 +82,15 @@
     values_builder.AddFormatted("a[%d] = 0x%08x;", i, kValues[i]);
   }
 
-  // Note that below source creates two different typed arrays with distinct
-  // elements kind to get coverage for both access patterns:
-  // - IsFixedTypedArrayElementsKind(x)
-  // - IsExternalArrayElementsKind(y)
+  // Note that below source creates two different typed arrays with the same
+  // elements kind to get coverage for both (on heap/with external backing
+  // store) access patterns.
   const char* source =
       "(function(a) {"
       "  var x = (a = new %sArray(%d)); %s;"
       "  var y = (a = new %sArray(%d)); %s; %%TypedArrayGetBuffer(y);"
       "  if (!%%HasFixed%sElements(x)) %%AbortJS('x');"
-      "  if (!%%HasExternal%sElements(y)) %%AbortJS('y');"
+      "  if (!%%HasFixed%sElements(y)) %%AbortJS('y');"
       "  function f(a,b) {"
       "    a = a | 0; b = b | 0;"
       "    var t = x[a];"
@@ -111,9 +108,9 @@
            values_buffer.start(), array_type, arraysize(kValues),
            values_buffer.start(), array_type, array_type);
 
-  FunctionTester T(
-      source_buffer.start(),
-      CompilationInfo::kContextSpecializing | CompilationInfo::kTypingEnabled);
+  FunctionTester T(source_buffer.start(),
+                   CompilationInfo::kFunctionContextSpecializing |
+                       CompilationInfo::kTypingEnabled);
   for (size_t i = 0; i < arraysize(kValues); ++i) {
     for (size_t j = 0; j < arraysize(kValues); ++j) {
       volatile U value_a = static_cast<U>(kValues[i]);
@@ -139,3 +136,7 @@
   TypedArrayStoreHelper<double>("Float64");
   // TODO(mstarzinger): Add tests for ClampedUint8.
 }
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/test/cctest/compiler/test-run-stackcheck.cc b/test/cctest/compiler/test-run-stackcheck.cc
index 8c1664b..52556ac 100644
--- a/test/cctest/compiler/test-run-stackcheck.cc
+++ b/test/cctest/compiler/test-run-stackcheck.cc
@@ -2,12 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "src/v8.h"
-
 #include "test/cctest/compiler/function-tester.h"
 
-using namespace v8::internal;
-using namespace v8::internal::compiler;
+namespace v8 {
+namespace internal {
+namespace compiler {
 
 TEST(TerminateAtMethodEntry) {
   FunctionTester T("(function(a,b) { return 23; })");
@@ -16,3 +15,7 @@
   T.isolate->stack_guard()->RequestTerminateExecution();
   T.CheckThrows(T.undefined(), T.undefined());
 }
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/test/cctest/compiler/test-run-stubs.cc b/test/cctest/compiler/test-run-stubs.cc
new file mode 100644
index 0000000..7a2a094
--- /dev/null
+++ b/test/cctest/compiler/test-run-stubs.cc
@@ -0,0 +1,69 @@
+// Copyright 2015 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/bootstrapper.h"
+#include "src/code-stubs.h"
+#include "src/compiler/common-operator.h"
+#include "src/compiler/graph.h"
+#include "src/compiler/js-graph.h"
+#include "src/compiler/js-operator.h"
+#include "src/compiler/linkage.h"
+#include "src/compiler/machine-operator.h"
+#include "src/compiler/pipeline.h"
+#include "src/parsing/parser.h"
+#include "test/cctest/compiler/function-tester.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+
+TEST(RunStringLengthStub) {
+  HandleAndZoneScope scope;
+  Isolate* isolate = scope.main_isolate();
+  Zone* zone = scope.main_zone();
+
+  // Create code and an accompanying descriptor.
+  StringLengthStub stub(isolate);
+  Handle<Code> code = stub.GenerateCode();
+  CompilationInfo info(&stub, isolate, zone);
+  CallDescriptor* descriptor = Linkage::ComputeIncoming(zone, &info);
+
+  // Create a function to call the code using the descriptor.
+  Graph graph(zone);
+  CommonOperatorBuilder common(zone);
+  // FunctionTester (ab)uses a 4-argument function
+  Node* start = graph.NewNode(common.Start(6));
+  // Parameter 0 is the receiver
+  Node* receiverParam = graph.NewNode(common.Parameter(1), start);
+  Node* nameParam = graph.NewNode(common.Parameter(2), start);
+  Node* slotParam = graph.NewNode(common.Parameter(3), start);
+  Node* vectorParam = graph.NewNode(common.Parameter(4), start);
+  Node* theCode = graph.NewNode(common.HeapConstant(code));
+  Node* dummyContext = graph.NewNode(common.NumberConstant(0.0));
+  Node* call =
+      graph.NewNode(common.Call(descriptor), theCode, receiverParam, nameParam,
+                    slotParam, vectorParam, dummyContext, start, start);
+  Node* ret = graph.NewNode(common.Return(), call, call, start);
+  Node* end = graph.NewNode(common.End(1), ret);
+  graph.SetStart(start);
+  graph.SetEnd(end);
+  FunctionTester ft(&graph, 4);
+
+  // Actuall call through to the stub, verifying its result.
+  const char* testString = "Und das Lamm schrie HURZ!";
+  Handle<JSReceiver> receiverArg =
+      Object::ToObject(isolate, ft.Val(testString)).ToHandleChecked();
+  Handle<String> nameArg = ft.Val("length");
+  Handle<Object> slot = ft.Val(0.0);
+  Handle<Object> vector = ft.Val(0.0);
+  Handle<Object> result =
+      ft.Call(receiverArg, nameArg, slot, vector).ToHandleChecked();
+  CHECK_EQ(static_cast<int>(strlen(testString)), Smi::cast(*result)->value());
+}
+
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/test/cctest/compiler/test-run-variables.cc b/test/cctest/compiler/test-run-variables.cc
index bf86e0d..f856368 100644
--- a/test/cctest/compiler/test-run-variables.cc
+++ b/test/cctest/compiler/test-run-variables.cc
@@ -2,12 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "src/v8.h"
-
 #include "test/cctest/compiler/function-tester.h"
 
-using namespace v8::internal;
-using namespace v8::internal::compiler;
+namespace v8 {
+namespace internal {
+namespace compiler {
 
 static const char* throws = NULL;
 
@@ -49,7 +48,7 @@
 
 
 static void RunVariableTests(const char* source, const char* tests[]) {
-  FLAG_harmony_scoping = true;
+  i::FLAG_legacy_const = true;
   EmbeddedVector<char, 512> buffer;
 
   for (int i = 0; tests[i] != NULL; i += 3) {
@@ -119,3 +118,7 @@
   CompileRun("var self = 'not a function'");
   T.CheckCall(T.function);
 }
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/test/cctest/compiler/test-schedule.cc b/test/cctest/compiler/test-schedule.cc
deleted file mode 100644
index 1eb3547..0000000
--- a/test/cctest/compiler/test-schedule.cc
+++ /dev/null
@@ -1,177 +0,0 @@
-// Copyright 2013 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "src/v8.h"
-
-#include "src/compiler/common-operator.h"
-#include "src/compiler/graph.h"
-#include "src/compiler/machine-operator.h"
-#include "src/compiler/node.h"
-#include "src/compiler/operator.h"
-#include "src/compiler/schedule.h"
-#include "test/cctest/cctest.h"
-
-using namespace v8::internal;
-using namespace v8::internal::compiler;
-
-static Operator dummy_operator(IrOpcode::kParameter, Operator::kNoWrite,
-                               "dummy", 0, 0, 0, 0, 0, 0);
-
-TEST(TestScheduleAllocation) {
-  HandleAndZoneScope scope;
-  Schedule schedule(scope.main_zone());
-
-  CHECK_NE(NULL, schedule.start());
-  CHECK_EQ(schedule.start(), schedule.GetBlockById(BasicBlock::Id::FromInt(0)));
-}
-
-
-TEST(TestScheduleAddNode) {
-  HandleAndZoneScope scope;
-  Schedule schedule(scope.main_zone());
-  Graph graph(scope.main_zone());
-  Node* n0 = graph.NewNode(&dummy_operator);
-  Node* n1 = graph.NewNode(&dummy_operator);
-
-  BasicBlock* entry = schedule.start();
-  schedule.AddNode(entry, n0);
-  schedule.AddNode(entry, n1);
-
-  CHECK_EQ(entry, schedule.block(n0));
-  CHECK_EQ(entry, schedule.block(n1));
-  CHECK(schedule.SameBasicBlock(n0, n1));
-
-  Node* n2 = graph.NewNode(&dummy_operator);
-  CHECK_EQ(NULL, schedule.block(n2));
-}
-
-
-TEST(TestScheduleAddGoto) {
-  HandleAndZoneScope scope;
-  Schedule schedule(scope.main_zone());
-
-  BasicBlock* entry = schedule.start();
-  BasicBlock* next = schedule.NewBasicBlock();
-
-  schedule.AddGoto(entry, next);
-
-  CHECK_EQ(0, static_cast<int>(entry->PredecessorCount()));
-  CHECK_EQ(1, static_cast<int>(entry->SuccessorCount()));
-  CHECK_EQ(next, entry->SuccessorAt(0));
-
-  CHECK_EQ(1, static_cast<int>(next->PredecessorCount()));
-  CHECK_EQ(entry, next->PredecessorAt(0));
-  CHECK_EQ(0, static_cast<int>(next->SuccessorCount()));
-}
-
-
-TEST(TestScheduleAddBranch) {
-  HandleAndZoneScope scope;
-  Schedule schedule(scope.main_zone());
-  Graph graph(scope.main_zone());
-  CommonOperatorBuilder common(scope.main_zone());
-  Node* n0 = graph.NewNode(&dummy_operator);
-  Node* b = graph.NewNode(common.Branch(), n0);
-
-  BasicBlock* entry = schedule.start();
-  BasicBlock* tblock = schedule.NewBasicBlock();
-  BasicBlock* fblock = schedule.NewBasicBlock();
-
-  schedule.AddBranch(entry, b, tblock, fblock);
-
-  CHECK_EQ(0, static_cast<int>(entry->PredecessorCount()));
-  CHECK_EQ(2, static_cast<int>(entry->SuccessorCount()));
-  CHECK_EQ(tblock, entry->SuccessorAt(0));
-  CHECK_EQ(fblock, entry->SuccessorAt(1));
-
-  CHECK_EQ(1, static_cast<int>(tblock->PredecessorCount()));
-  CHECK_EQ(entry, tblock->PredecessorAt(0));
-  CHECK_EQ(0, static_cast<int>(tblock->SuccessorCount()));
-
-  CHECK_EQ(1, static_cast<int>(fblock->PredecessorCount()));
-  CHECK_EQ(entry, fblock->PredecessorAt(0));
-  CHECK_EQ(0, static_cast<int>(fblock->SuccessorCount()));
-}
-
-
-TEST(TestScheduleAddReturn) {
-  HandleAndZoneScope scope;
-  Schedule schedule(scope.main_zone());
-  Graph graph(scope.main_zone());
-  Node* n0 = graph.NewNode(&dummy_operator);
-  BasicBlock* entry = schedule.start();
-  schedule.AddReturn(entry, n0);
-
-  CHECK_EQ(0, static_cast<int>(entry->PredecessorCount()));
-  CHECK_EQ(1, static_cast<int>(entry->SuccessorCount()));
-  CHECK_EQ(schedule.end(), entry->SuccessorAt(0));
-}
-
-
-TEST(TestScheduleAddThrow) {
-  HandleAndZoneScope scope;
-  Schedule schedule(scope.main_zone());
-  Graph graph(scope.main_zone());
-  Node* n0 = graph.NewNode(&dummy_operator);
-  BasicBlock* entry = schedule.start();
-  schedule.AddThrow(entry, n0);
-
-  CHECK_EQ(0, static_cast<int>(entry->PredecessorCount()));
-  CHECK_EQ(1, static_cast<int>(entry->SuccessorCount()));
-  CHECK_EQ(schedule.end(), entry->SuccessorAt(0));
-}
-
-
-TEST(TestScheduleInsertBranch) {
-  HandleAndZoneScope scope;
-  Schedule schedule(scope.main_zone());
-  Graph graph(scope.main_zone());
-  CommonOperatorBuilder common(scope.main_zone());
-  Node* n0 = graph.NewNode(&dummy_operator);
-  Node* n1 = graph.NewNode(&dummy_operator);
-  Node* b = graph.NewNode(common.Branch(), n1);
-
-  BasicBlock* entry = schedule.start();
-  BasicBlock* tblock = schedule.NewBasicBlock();
-  BasicBlock* fblock = schedule.NewBasicBlock();
-  BasicBlock* merge = schedule.NewBasicBlock();
-  schedule.AddReturn(entry, n0);
-  schedule.AddGoto(tblock, merge);
-  schedule.AddGoto(fblock, merge);
-
-  schedule.InsertBranch(entry, merge, b, tblock, fblock);
-
-  CHECK_EQ(0, static_cast<int>(entry->PredecessorCount()));
-  CHECK_EQ(2, static_cast<int>(entry->SuccessorCount()));
-  CHECK_EQ(tblock, entry->SuccessorAt(0));
-  CHECK_EQ(fblock, entry->SuccessorAt(1));
-
-  CHECK_EQ(2, static_cast<int>(merge->PredecessorCount()));
-  CHECK_EQ(1, static_cast<int>(merge->SuccessorCount()));
-  CHECK_EQ(schedule.end(), merge->SuccessorAt(0));
-
-  CHECK_EQ(1, static_cast<int>(schedule.end()->PredecessorCount()));
-  CHECK_EQ(0, static_cast<int>(schedule.end()->SuccessorCount()));
-  CHECK_EQ(merge, schedule.end()->PredecessorAt(0));
-}
-
-
-TEST(BuildMulNodeGraph) {
-  HandleAndZoneScope scope;
-  Schedule schedule(scope.main_zone());
-  Graph graph(scope.main_zone());
-  CommonOperatorBuilder common(scope.main_zone());
-  // TODO(titzer): use test operators.
-  MachineOperatorBuilder machine(scope.main_zone());
-
-  Node* start = graph.NewNode(common.Start(0));
-  graph.SetStart(start);
-  Node* param0 = graph.NewNode(common.Parameter(0), graph.start());
-  Node* param1 = graph.NewNode(common.Parameter(1), graph.start());
-
-  Node* mul = graph.NewNode(machine.Int32Mul(), param0, param1);
-  Node* ret = graph.NewNode(common.Return(), mul, start);
-
-  USE(ret);
-}
diff --git a/test/cctest/compiler/test-scheduler.cc b/test/cctest/compiler/test-scheduler.cc
deleted file mode 100644
index 1b79ed5..0000000
--- a/test/cctest/compiler/test-scheduler.cc
+++ /dev/null
@@ -1,2124 +0,0 @@
-// Copyright 2014 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "src/v8.h"
-
-#include "src/compiler/access-builder.h"
-#include "src/compiler/common-operator.h"
-#include "src/compiler/graph.h"
-#include "src/compiler/graph-visualizer.h"
-#include "src/compiler/js-operator.h"
-#include "src/compiler/node.h"
-#include "src/compiler/opcodes.h"
-#include "src/compiler/operator.h"
-#include "src/compiler/schedule.h"
-#include "src/compiler/scheduler.h"
-#include "src/compiler/simplified-operator.h"
-#include "src/compiler/verifier.h"
-#include "test/cctest/cctest.h"
-
-using namespace v8::internal;
-using namespace v8::internal::compiler;
-
-Operator kIntAdd(IrOpcode::kInt32Add, Operator::kPure, "Int32Add", 2, 0, 0, 1,
-                 0, 0);
-
-// TODO(titzer): pull RPO tests out to their own file.
-static void CheckRPONumbers(BasicBlockVector* order, size_t expected,
-                            bool loops_allowed) {
-  CHECK(expected == order->size());
-  for (int i = 0; i < static_cast<int>(order->size()); i++) {
-    CHECK(order->at(i)->rpo_number() == i);
-    if (!loops_allowed) {
-      CHECK_EQ(NULL, order->at(i)->loop_end());
-      CHECK_EQ(NULL, order->at(i)->loop_header());
-    }
-  }
-}
-
-
-static void CheckLoop(BasicBlockVector* order, BasicBlock** blocks,
-                      int body_size) {
-  BasicBlock* header = blocks[0];
-  BasicBlock* end = header->loop_end();
-  CHECK_NE(NULL, end);
-  CHECK_GT(end->rpo_number(), 0);
-  CHECK_EQ(body_size, end->rpo_number() - header->rpo_number());
-  for (int i = 0; i < body_size; i++) {
-    CHECK_GE(blocks[i]->rpo_number(), header->rpo_number());
-    CHECK_LT(blocks[i]->rpo_number(), end->rpo_number());
-    CHECK(header->LoopContains(blocks[i]));
-    CHECK(header->IsLoopHeader() || blocks[i]->loop_header() == header);
-  }
-  if (header->rpo_number() > 0) {
-    CHECK_NE(order->at(header->rpo_number() - 1)->loop_header(), header);
-  }
-  if (end->rpo_number() < static_cast<int>(order->size())) {
-    CHECK_NE(order->at(end->rpo_number())->loop_header(), header);
-  }
-}
-
-
-struct TestLoop {
-  int count;
-  BasicBlock** nodes;
-  BasicBlock* header() { return nodes[0]; }
-  BasicBlock* last() { return nodes[count - 1]; }
-  ~TestLoop() { delete[] nodes; }
-
-  void Check(BasicBlockVector* order) { CheckLoop(order, nodes, count); }
-};
-
-
-static TestLoop* CreateLoop(Schedule* schedule, int count) {
-  TestLoop* loop = new TestLoop();
-  loop->count = count;
-  loop->nodes = new BasicBlock* [count];
-  for (int i = 0; i < count; i++) {
-    loop->nodes[i] = schedule->NewBasicBlock();
-    if (i > 0) {
-      schedule->AddSuccessorForTesting(loop->nodes[i - 1], loop->nodes[i]);
-    }
-  }
-  schedule->AddSuccessorForTesting(loop->nodes[count - 1], loop->nodes[0]);
-  return loop;
-}
-
-
-static int GetScheduledNodeCount(Schedule* schedule) {
-  int node_count = 0;
-  for (BasicBlockVectorIter i = schedule->rpo_order()->begin();
-       i != schedule->rpo_order()->end(); ++i) {
-    BasicBlock* block = *i;
-    for (BasicBlock::const_iterator j = block->begin(); j != block->end();
-         ++j) {
-      ++node_count;
-    }
-    BasicBlock::Control control = block->control();
-    if (control != BasicBlock::kNone) {
-      ++node_count;
-    }
-  }
-  return node_count;
-}
-
-
-static Schedule* ComputeAndVerifySchedule(int expected, Graph* graph) {
-  if (FLAG_trace_turbo) {
-    OFStream os(stdout);
-    os << AsDOT(*graph);
-  }
-
-  Schedule* schedule = Scheduler::ComputeSchedule(graph->zone(), graph);
-
-  if (FLAG_trace_turbo_scheduler) {
-    OFStream os(stdout);
-    os << *schedule << std::endl;
-  }
-  ScheduleVerifier::Run(schedule);
-  CHECK_EQ(expected, GetScheduledNodeCount(schedule));
-  return schedule;
-}
-
-
-TEST(RPODegenerate1) {
-  HandleAndZoneScope scope;
-  Schedule schedule(scope.main_zone());
-
-  BasicBlockVector* order =
-      Scheduler::ComputeSpecialRPO(scope.main_zone(), &schedule);
-  CheckRPONumbers(order, 1, false);
-  CHECK_EQ(schedule.start(), order->at(0));
-}
-
-
-TEST(RPODegenerate2) {
-  HandleAndZoneScope scope;
-  Schedule schedule(scope.main_zone());
-
-  schedule.AddGoto(schedule.start(), schedule.end());
-  BasicBlockVector* order =
-      Scheduler::ComputeSpecialRPO(scope.main_zone(), &schedule);
-  CheckRPONumbers(order, 2, false);
-  CHECK_EQ(schedule.start(), order->at(0));
-  CHECK_EQ(schedule.end(), order->at(1));
-}
-
-
-TEST(RPOLine) {
-  HandleAndZoneScope scope;
-
-  for (int i = 0; i < 10; i++) {
-    Schedule schedule(scope.main_zone());
-
-    BasicBlock* last = schedule.start();
-    for (int j = 0; j < i; j++) {
-      BasicBlock* block = schedule.NewBasicBlock();
-      block->set_deferred(i & 1);
-      schedule.AddGoto(last, block);
-      last = block;
-    }
-    BasicBlockVector* order =
-        Scheduler::ComputeSpecialRPO(scope.main_zone(), &schedule);
-    CheckRPONumbers(order, 1 + i, false);
-
-    for (size_t i = 0; i < schedule.BasicBlockCount(); i++) {
-      BasicBlock* block = schedule.GetBlockById(BasicBlock::Id::FromSize(i));
-      if (block->rpo_number() >= 0 && block->SuccessorCount() == 1) {
-        CHECK(block->rpo_number() + 1 == block->SuccessorAt(0)->rpo_number());
-      }
-    }
-  }
-}
-
-
-TEST(RPOSelfLoop) {
-  HandleAndZoneScope scope;
-  Schedule schedule(scope.main_zone());
-  schedule.AddSuccessorForTesting(schedule.start(), schedule.start());
-  BasicBlockVector* order =
-      Scheduler::ComputeSpecialRPO(scope.main_zone(), &schedule);
-  CheckRPONumbers(order, 1, true);
-  BasicBlock* loop[] = {schedule.start()};
-  CheckLoop(order, loop, 1);
-}
-
-
-TEST(RPOEntryLoop) {
-  HandleAndZoneScope scope;
-  Schedule schedule(scope.main_zone());
-  BasicBlock* body = schedule.NewBasicBlock();
-  schedule.AddSuccessorForTesting(schedule.start(), body);
-  schedule.AddSuccessorForTesting(body, schedule.start());
-  BasicBlockVector* order =
-      Scheduler::ComputeSpecialRPO(scope.main_zone(), &schedule);
-  CheckRPONumbers(order, 2, true);
-  BasicBlock* loop[] = {schedule.start(), body};
-  CheckLoop(order, loop, 2);
-}
-
-
-TEST(RPOEndLoop) {
-  HandleAndZoneScope scope;
-  Schedule schedule(scope.main_zone());
-  SmartPointer<TestLoop> loop1(CreateLoop(&schedule, 2));
-  schedule.AddSuccessorForTesting(schedule.start(), loop1->header());
-  BasicBlockVector* order =
-      Scheduler::ComputeSpecialRPO(scope.main_zone(), &schedule);
-  CheckRPONumbers(order, 3, true);
-  loop1->Check(order);
-}
-
-
-TEST(RPOEndLoopNested) {
-  HandleAndZoneScope scope;
-  Schedule schedule(scope.main_zone());
-  SmartPointer<TestLoop> loop1(CreateLoop(&schedule, 2));
-  schedule.AddSuccessorForTesting(schedule.start(), loop1->header());
-  schedule.AddSuccessorForTesting(loop1->last(), schedule.start());
-  BasicBlockVector* order =
-      Scheduler::ComputeSpecialRPO(scope.main_zone(), &schedule);
-  CheckRPONumbers(order, 3, true);
-  loop1->Check(order);
-}
-
-
-TEST(RPODiamond) {
-  HandleAndZoneScope scope;
-  Schedule schedule(scope.main_zone());
-
-  BasicBlock* A = schedule.start();
-  BasicBlock* B = schedule.NewBasicBlock();
-  BasicBlock* C = schedule.NewBasicBlock();
-  BasicBlock* D = schedule.end();
-
-  schedule.AddSuccessorForTesting(A, B);
-  schedule.AddSuccessorForTesting(A, C);
-  schedule.AddSuccessorForTesting(B, D);
-  schedule.AddSuccessorForTesting(C, D);
-
-  BasicBlockVector* order =
-      Scheduler::ComputeSpecialRPO(scope.main_zone(), &schedule);
-  CheckRPONumbers(order, 4, false);
-
-  CHECK_EQ(0, A->rpo_number());
-  CHECK((B->rpo_number() == 1 && C->rpo_number() == 2) ||
-        (B->rpo_number() == 2 && C->rpo_number() == 1));
-  CHECK_EQ(3, D->rpo_number());
-}
-
-
-TEST(RPOLoop1) {
-  HandleAndZoneScope scope;
-  Schedule schedule(scope.main_zone());
-
-  BasicBlock* A = schedule.start();
-  BasicBlock* B = schedule.NewBasicBlock();
-  BasicBlock* C = schedule.NewBasicBlock();
-  BasicBlock* D = schedule.end();
-
-  schedule.AddSuccessorForTesting(A, B);
-  schedule.AddSuccessorForTesting(B, C);
-  schedule.AddSuccessorForTesting(C, B);
-  schedule.AddSuccessorForTesting(C, D);
-
-  BasicBlockVector* order =
-      Scheduler::ComputeSpecialRPO(scope.main_zone(), &schedule);
-  CheckRPONumbers(order, 4, true);
-  BasicBlock* loop[] = {B, C};
-  CheckLoop(order, loop, 2);
-}
-
-
-TEST(RPOLoop2) {
-  HandleAndZoneScope scope;
-  Schedule schedule(scope.main_zone());
-
-  BasicBlock* A = schedule.start();
-  BasicBlock* B = schedule.NewBasicBlock();
-  BasicBlock* C = schedule.NewBasicBlock();
-  BasicBlock* D = schedule.end();
-
-  schedule.AddSuccessorForTesting(A, B);
-  schedule.AddSuccessorForTesting(B, C);
-  schedule.AddSuccessorForTesting(C, B);
-  schedule.AddSuccessorForTesting(B, D);
-
-  BasicBlockVector* order =
-      Scheduler::ComputeSpecialRPO(scope.main_zone(), &schedule);
-  CheckRPONumbers(order, 4, true);
-  BasicBlock* loop[] = {B, C};
-  CheckLoop(order, loop, 2);
-}
-
-
-TEST(RPOLoopN) {
-  HandleAndZoneScope scope;
-
-  for (int i = 0; i < 11; i++) {
-    Schedule schedule(scope.main_zone());
-    BasicBlock* A = schedule.start();
-    BasicBlock* B = schedule.NewBasicBlock();
-    BasicBlock* C = schedule.NewBasicBlock();
-    BasicBlock* D = schedule.NewBasicBlock();
-    BasicBlock* E = schedule.NewBasicBlock();
-    BasicBlock* F = schedule.NewBasicBlock();
-    BasicBlock* G = schedule.end();
-
-    schedule.AddSuccessorForTesting(A, B);
-    schedule.AddSuccessorForTesting(B, C);
-    schedule.AddSuccessorForTesting(C, D);
-    schedule.AddSuccessorForTesting(D, E);
-    schedule.AddSuccessorForTesting(E, F);
-    schedule.AddSuccessorForTesting(F, B);
-    schedule.AddSuccessorForTesting(B, G);
-
-    // Throw in extra backedges from time to time.
-    if (i == 1) schedule.AddSuccessorForTesting(B, B);
-    if (i == 2) schedule.AddSuccessorForTesting(C, B);
-    if (i == 3) schedule.AddSuccessorForTesting(D, B);
-    if (i == 4) schedule.AddSuccessorForTesting(E, B);
-    if (i == 5) schedule.AddSuccessorForTesting(F, B);
-
-    // Throw in extra loop exits from time to time.
-    if (i == 6) schedule.AddSuccessorForTesting(B, G);
-    if (i == 7) schedule.AddSuccessorForTesting(C, G);
-    if (i == 8) schedule.AddSuccessorForTesting(D, G);
-    if (i == 9) schedule.AddSuccessorForTesting(E, G);
-    if (i == 10) schedule.AddSuccessorForTesting(F, G);
-
-    BasicBlockVector* order =
-        Scheduler::ComputeSpecialRPO(scope.main_zone(), &schedule);
-    CheckRPONumbers(order, 7, true);
-    BasicBlock* loop[] = {B, C, D, E, F};
-    CheckLoop(order, loop, 5);
-  }
-}
-
-
-TEST(RPOLoopNest1) {
-  HandleAndZoneScope scope;
-  Schedule schedule(scope.main_zone());
-
-  BasicBlock* A = schedule.start();
-  BasicBlock* B = schedule.NewBasicBlock();
-  BasicBlock* C = schedule.NewBasicBlock();
-  BasicBlock* D = schedule.NewBasicBlock();
-  BasicBlock* E = schedule.NewBasicBlock();
-  BasicBlock* F = schedule.end();
-
-  schedule.AddSuccessorForTesting(A, B);
-  schedule.AddSuccessorForTesting(B, C);
-  schedule.AddSuccessorForTesting(C, D);
-  schedule.AddSuccessorForTesting(D, C);
-  schedule.AddSuccessorForTesting(D, E);
-  schedule.AddSuccessorForTesting(E, B);
-  schedule.AddSuccessorForTesting(E, F);
-
-  BasicBlockVector* order =
-      Scheduler::ComputeSpecialRPO(scope.main_zone(), &schedule);
-  CheckRPONumbers(order, 6, true);
-  BasicBlock* loop1[] = {B, C, D, E};
-  CheckLoop(order, loop1, 4);
-
-  BasicBlock* loop2[] = {C, D};
-  CheckLoop(order, loop2, 2);
-}
-
-
-TEST(RPOLoopNest2) {
-  HandleAndZoneScope scope;
-  Schedule schedule(scope.main_zone());
-
-  BasicBlock* A = schedule.start();
-  BasicBlock* B = schedule.NewBasicBlock();
-  BasicBlock* C = schedule.NewBasicBlock();
-  BasicBlock* D = schedule.NewBasicBlock();
-  BasicBlock* E = schedule.NewBasicBlock();
-  BasicBlock* F = schedule.NewBasicBlock();
-  BasicBlock* G = schedule.NewBasicBlock();
-  BasicBlock* H = schedule.end();
-
-  schedule.AddSuccessorForTesting(A, B);
-  schedule.AddSuccessorForTesting(B, C);
-  schedule.AddSuccessorForTesting(C, D);
-  schedule.AddSuccessorForTesting(D, E);
-  schedule.AddSuccessorForTesting(E, F);
-  schedule.AddSuccessorForTesting(F, G);
-  schedule.AddSuccessorForTesting(G, H);
-
-  schedule.AddSuccessorForTesting(E, D);
-  schedule.AddSuccessorForTesting(F, C);
-  schedule.AddSuccessorForTesting(G, B);
-
-  BasicBlockVector* order =
-      Scheduler::ComputeSpecialRPO(scope.main_zone(), &schedule);
-  CheckRPONumbers(order, 8, true);
-  BasicBlock* loop1[] = {B, C, D, E, F, G};
-  CheckLoop(order, loop1, 6);
-
-  BasicBlock* loop2[] = {C, D, E, F};
-  CheckLoop(order, loop2, 4);
-
-  BasicBlock* loop3[] = {D, E};
-  CheckLoop(order, loop3, 2);
-}
-
-
-TEST(RPOLoopFollow1) {
-  HandleAndZoneScope scope;
-  Schedule schedule(scope.main_zone());
-
-  SmartPointer<TestLoop> loop1(CreateLoop(&schedule, 1));
-  SmartPointer<TestLoop> loop2(CreateLoop(&schedule, 1));
-
-  BasicBlock* A = schedule.start();
-  BasicBlock* E = schedule.end();
-
-  schedule.AddSuccessorForTesting(A, loop1->header());
-  schedule.AddSuccessorForTesting(loop1->header(), loop2->header());
-  schedule.AddSuccessorForTesting(loop2->last(), E);
-
-  BasicBlockVector* order =
-      Scheduler::ComputeSpecialRPO(scope.main_zone(), &schedule);
-
-  CHECK_EQ(static_cast<int>(schedule.BasicBlockCount()),
-           static_cast<int>(order->size()));
-
-  loop1->Check(order);
-  loop2->Check(order);
-}
-
-
-TEST(RPOLoopFollow2) {
-  HandleAndZoneScope scope;
-  Schedule schedule(scope.main_zone());
-
-  SmartPointer<TestLoop> loop1(CreateLoop(&schedule, 1));
-  SmartPointer<TestLoop> loop2(CreateLoop(&schedule, 1));
-
-  BasicBlock* A = schedule.start();
-  BasicBlock* S = schedule.NewBasicBlock();
-  BasicBlock* E = schedule.end();
-
-  schedule.AddSuccessorForTesting(A, loop1->header());
-  schedule.AddSuccessorForTesting(loop1->header(), S);
-  schedule.AddSuccessorForTesting(S, loop2->header());
-  schedule.AddSuccessorForTesting(loop2->last(), E);
-
-  BasicBlockVector* order =
-      Scheduler::ComputeSpecialRPO(scope.main_zone(), &schedule);
-
-  CHECK_EQ(static_cast<int>(schedule.BasicBlockCount()),
-           static_cast<int>(order->size()));
-  loop1->Check(order);
-  loop2->Check(order);
-}
-
-
-TEST(RPOLoopFollowN) {
-  HandleAndZoneScope scope;
-
-  for (int size = 1; size < 5; size++) {
-    for (int exit = 0; exit < size; exit++) {
-      Schedule schedule(scope.main_zone());
-      SmartPointer<TestLoop> loop1(CreateLoop(&schedule, size));
-      SmartPointer<TestLoop> loop2(CreateLoop(&schedule, size));
-      BasicBlock* A = schedule.start();
-      BasicBlock* E = schedule.end();
-
-      schedule.AddSuccessorForTesting(A, loop1->header());
-      schedule.AddSuccessorForTesting(loop1->nodes[exit], loop2->header());
-      schedule.AddSuccessorForTesting(loop2->nodes[exit], E);
-      BasicBlockVector* order =
-          Scheduler::ComputeSpecialRPO(scope.main_zone(), &schedule);
-
-      CHECK_EQ(static_cast<int>(schedule.BasicBlockCount()),
-               static_cast<int>(order->size()));
-      loop1->Check(order);
-      loop2->Check(order);
-    }
-  }
-}
-
-
-TEST(RPONestedLoopFollow1) {
-  HandleAndZoneScope scope;
-  Schedule schedule(scope.main_zone());
-
-  SmartPointer<TestLoop> loop1(CreateLoop(&schedule, 1));
-  SmartPointer<TestLoop> loop2(CreateLoop(&schedule, 1));
-
-  BasicBlock* A = schedule.start();
-  BasicBlock* B = schedule.NewBasicBlock();
-  BasicBlock* C = schedule.NewBasicBlock();
-  BasicBlock* E = schedule.end();
-
-  schedule.AddSuccessorForTesting(A, B);
-  schedule.AddSuccessorForTesting(B, loop1->header());
-  schedule.AddSuccessorForTesting(loop1->header(), loop2->header());
-  schedule.AddSuccessorForTesting(loop2->last(), C);
-  schedule.AddSuccessorForTesting(C, E);
-  schedule.AddSuccessorForTesting(C, B);
-
-  BasicBlockVector* order =
-      Scheduler::ComputeSpecialRPO(scope.main_zone(), &schedule);
-
-  CHECK_EQ(static_cast<int>(schedule.BasicBlockCount()),
-           static_cast<int>(order->size()));
-  loop1->Check(order);
-  loop2->Check(order);
-
-  BasicBlock* loop3[] = {B, loop1->nodes[0], loop2->nodes[0], C};
-  CheckLoop(order, loop3, 4);
-}
-
-
-TEST(RPOLoopBackedges1) {
-  HandleAndZoneScope scope;
-
-  int size = 8;
-  for (int i = 0; i < size; i++) {
-    for (int j = 0; j < size; j++) {
-      Schedule schedule(scope.main_zone());
-      BasicBlock* A = schedule.start();
-      BasicBlock* E = schedule.end();
-
-      SmartPointer<TestLoop> loop1(CreateLoop(&schedule, size));
-      schedule.AddSuccessorForTesting(A, loop1->header());
-      schedule.AddSuccessorForTesting(loop1->last(), E);
-
-      schedule.AddSuccessorForTesting(loop1->nodes[i], loop1->header());
-      schedule.AddSuccessorForTesting(loop1->nodes[j], E);
-
-      BasicBlockVector* order =
-          Scheduler::ComputeSpecialRPO(scope.main_zone(), &schedule);
-      CheckRPONumbers(order, schedule.BasicBlockCount(), true);
-      loop1->Check(order);
-    }
-  }
-}
-
-
-TEST(RPOLoopOutedges1) {
-  HandleAndZoneScope scope;
-
-  int size = 8;
-  for (int i = 0; i < size; i++) {
-    for (int j = 0; j < size; j++) {
-      Schedule schedule(scope.main_zone());
-      BasicBlock* A = schedule.start();
-      BasicBlock* D = schedule.NewBasicBlock();
-      BasicBlock* E = schedule.end();
-
-      SmartPointer<TestLoop> loop1(CreateLoop(&schedule, size));
-      schedule.AddSuccessorForTesting(A, loop1->header());
-      schedule.AddSuccessorForTesting(loop1->last(), E);
-
-      schedule.AddSuccessorForTesting(loop1->nodes[i], loop1->header());
-      schedule.AddSuccessorForTesting(loop1->nodes[j], D);
-      schedule.AddSuccessorForTesting(D, E);
-
-      BasicBlockVector* order =
-          Scheduler::ComputeSpecialRPO(scope.main_zone(), &schedule);
-      CheckRPONumbers(order, schedule.BasicBlockCount(), true);
-      loop1->Check(order);
-    }
-  }
-}
-
-
-TEST(RPOLoopOutedges2) {
-  HandleAndZoneScope scope;
-
-  int size = 8;
-  for (int i = 0; i < size; i++) {
-    Schedule schedule(scope.main_zone());
-    BasicBlock* A = schedule.start();
-    BasicBlock* E = schedule.end();
-
-    SmartPointer<TestLoop> loop1(CreateLoop(&schedule, size));
-    schedule.AddSuccessorForTesting(A, loop1->header());
-    schedule.AddSuccessorForTesting(loop1->last(), E);
-
-    for (int j = 0; j < size; j++) {
-      BasicBlock* O = schedule.NewBasicBlock();
-      schedule.AddSuccessorForTesting(loop1->nodes[j], O);
-      schedule.AddSuccessorForTesting(O, E);
-    }
-
-    BasicBlockVector* order =
-        Scheduler::ComputeSpecialRPO(scope.main_zone(), &schedule);
-    CheckRPONumbers(order, schedule.BasicBlockCount(), true);
-    loop1->Check(order);
-  }
-}
-
-
-TEST(RPOLoopOutloops1) {
-  HandleAndZoneScope scope;
-
-  int size = 8;
-  for (int i = 0; i < size; i++) {
-    Schedule schedule(scope.main_zone());
-    BasicBlock* A = schedule.start();
-    BasicBlock* E = schedule.end();
-    SmartPointer<TestLoop> loop1(CreateLoop(&schedule, size));
-    schedule.AddSuccessorForTesting(A, loop1->header());
-    schedule.AddSuccessorForTesting(loop1->last(), E);
-
-    TestLoop** loopN = new TestLoop* [size];
-    for (int j = 0; j < size; j++) {
-      loopN[j] = CreateLoop(&schedule, 2);
-      schedule.AddSuccessorForTesting(loop1->nodes[j], loopN[j]->header());
-      schedule.AddSuccessorForTesting(loopN[j]->last(), E);
-    }
-
-    BasicBlockVector* order =
-        Scheduler::ComputeSpecialRPO(scope.main_zone(), &schedule);
-    CheckRPONumbers(order, schedule.BasicBlockCount(), true);
-    loop1->Check(order);
-
-    for (int j = 0; j < size; j++) {
-      loopN[j]->Check(order);
-      delete loopN[j];
-    }
-    delete[] loopN;
-  }
-}
-
-
-TEST(RPOLoopMultibackedge) {
-  HandleAndZoneScope scope;
-  Schedule schedule(scope.main_zone());
-
-  BasicBlock* A = schedule.start();
-  BasicBlock* B = schedule.NewBasicBlock();
-  BasicBlock* C = schedule.NewBasicBlock();
-  BasicBlock* D = schedule.NewBasicBlock();
-  BasicBlock* E = schedule.NewBasicBlock();
-
-  schedule.AddSuccessorForTesting(A, B);
-  schedule.AddSuccessorForTesting(B, C);
-  schedule.AddSuccessorForTesting(B, D);
-  schedule.AddSuccessorForTesting(B, E);
-  schedule.AddSuccessorForTesting(C, B);
-  schedule.AddSuccessorForTesting(D, B);
-  schedule.AddSuccessorForTesting(E, B);
-
-  BasicBlockVector* order =
-      Scheduler::ComputeSpecialRPO(scope.main_zone(), &schedule);
-  CheckRPONumbers(order, 5, true);
-
-  BasicBlock* loop1[] = {B, C, D, E};
-  CheckLoop(order, loop1, 4);
-}
-
-
-TEST(BuildScheduleEmpty) {
-  HandleAndZoneScope scope;
-  Graph graph(scope.main_zone());
-  CommonOperatorBuilder builder(scope.main_zone());
-  graph.SetStart(graph.NewNode(builder.Start(0)));
-  graph.SetEnd(graph.NewNode(builder.End(), graph.start()));
-
-  USE(Scheduler::ComputeSchedule(scope.main_zone(), &graph));
-}
-
-
-TEST(BuildScheduleOneParameter) {
-  HandleAndZoneScope scope;
-  Graph graph(scope.main_zone());
-  CommonOperatorBuilder builder(scope.main_zone());
-  graph.SetStart(graph.NewNode(builder.Start(0)));
-
-  Node* p1 = graph.NewNode(builder.Parameter(0), graph.start());
-  Node* ret = graph.NewNode(builder.Return(), p1, graph.start(), graph.start());
-
-  graph.SetEnd(graph.NewNode(builder.End(), ret));
-
-  USE(Scheduler::ComputeSchedule(scope.main_zone(), &graph));
-}
-
-
-TEST(BuildScheduleIfSplit) {
-  HandleAndZoneScope scope;
-  Graph graph(scope.main_zone());
-  CommonOperatorBuilder builder(scope.main_zone());
-  JSOperatorBuilder js_builder(scope.main_zone());
-  graph.SetStart(graph.NewNode(builder.Start(3)));
-
-  Node* p1 = graph.NewNode(builder.Parameter(0), graph.start());
-  Node* p2 = graph.NewNode(builder.Parameter(1), graph.start());
-  Node* p3 = graph.NewNode(builder.Parameter(2), graph.start());
-  Node* p4 = graph.NewNode(builder.Parameter(3), graph.start());
-  Node* p5 = graph.NewNode(builder.Parameter(4), graph.start());
-  Node* cmp = graph.NewNode(js_builder.LessThanOrEqual(), p1, p2, p3,
-                            graph.start(), graph.start());
-  Node* branch = graph.NewNode(builder.Branch(), cmp, graph.start());
-  Node* true_branch = graph.NewNode(builder.IfTrue(), branch);
-  Node* false_branch = graph.NewNode(builder.IfFalse(), branch);
-
-  Node* ret1 = graph.NewNode(builder.Return(), p4, graph.start(), true_branch);
-  Node* ret2 = graph.NewNode(builder.Return(), p5, graph.start(), false_branch);
-  Node* merge = graph.NewNode(builder.Merge(2), ret1, ret2);
-  graph.SetEnd(graph.NewNode(builder.End(), merge));
-
-  ComputeAndVerifySchedule(13, &graph);
-}
-
-
-TEST(BuildScheduleIfSplitWithEffects) {
-  HandleAndZoneScope scope;
-  Isolate* isolate = scope.main_isolate();
-  Graph graph(scope.main_zone());
-  CommonOperatorBuilder common_builder(scope.main_zone());
-  JSOperatorBuilder js_builder(scope.main_zone());
-  const Operator* op;
-
-  Handle<HeapObject> object =
-      Handle<HeapObject>(isolate->heap()->undefined_value(), isolate);
-  Unique<HeapObject> unique_constant =
-      Unique<HeapObject>::CreateUninitialized(object);
-
-  // Manually transcripted code for:
-  // function turbo_fan_test(a, b, c, y) {
-  //   if (a < b) {
-  //     return a + b - c * c - a + y;
-  //   } else {
-  //     return c * c - a;
-  //   }
-  // }
-  op = common_builder.Start(0);
-  Node* n0 = graph.NewNode(op);
-  USE(n0);
-  Node* nil = graph.NewNode(common_builder.Dead());
-  op = common_builder.End();
-  Node* n23 = graph.NewNode(op, nil);
-  USE(n23);
-  op = common_builder.Merge(2);
-  Node* n22 = graph.NewNode(op, nil, nil);
-  USE(n22);
-  op = common_builder.Return();
-  Node* n16 = graph.NewNode(op, nil, nil, nil);
-  USE(n16);
-  op = js_builder.Add();
-  Node* n15 = graph.NewNode(op, nil, nil, nil, nil, nil);
-  USE(n15);
-  op = js_builder.Subtract();
-  Node* n14 = graph.NewNode(op, nil, nil, nil, nil, nil);
-  USE(n14);
-  op = js_builder.Subtract();
-  Node* n13 = graph.NewNode(op, nil, nil, nil, nil, nil);
-  USE(n13);
-  op = js_builder.Add();
-  Node* n11 = graph.NewNode(op, nil, nil, nil, nil, nil);
-  USE(n11);
-  op = common_builder.Parameter(0);
-  Node* n2 = graph.NewNode(op, n0);
-  USE(n2);
-  n11->ReplaceInput(0, n2);
-  op = common_builder.Parameter(0);
-  Node* n3 = graph.NewNode(op, n0);
-  USE(n3);
-  n11->ReplaceInput(1, n3);
-  op = common_builder.HeapConstant(unique_constant);
-  Node* n7 = graph.NewNode(op);
-  USE(n7);
-  n11->ReplaceInput(2, n7);
-  op = js_builder.LessThan();
-  Node* n8 = graph.NewNode(op, nil, nil, nil, nil, nil);
-  USE(n8);
-  n8->ReplaceInput(0, n2);
-  n8->ReplaceInput(1, n3);
-  n8->ReplaceInput(2, n7);
-  n8->ReplaceInput(3, n0);
-  n8->ReplaceInput(4, n0);
-  n11->ReplaceInput(3, n8);
-  op = common_builder.IfTrue();
-  Node* n10 = graph.NewNode(op, nil);
-  USE(n10);
-  op = common_builder.Branch();
-  Node* n9 = graph.NewNode(op, nil, nil);
-  USE(n9);
-  n9->ReplaceInput(0, n8);
-  n9->ReplaceInput(1, n0);
-  n10->ReplaceInput(0, n9);
-  n11->ReplaceInput(4, n10);
-  n13->ReplaceInput(0, n11);
-  op = js_builder.Multiply();
-  Node* n12 = graph.NewNode(op, nil, nil, nil, nil, nil);
-  USE(n12);
-  op = common_builder.Parameter(0);
-  Node* n4 = graph.NewNode(op, n0);
-  USE(n4);
-  n12->ReplaceInput(0, n4);
-  n12->ReplaceInput(1, n4);
-  n12->ReplaceInput(2, n7);
-  n12->ReplaceInput(3, n11);
-  n12->ReplaceInput(4, n10);
-  n13->ReplaceInput(1, n12);
-  n13->ReplaceInput(2, n7);
-  n13->ReplaceInput(3, n12);
-  n13->ReplaceInput(4, n10);
-  n14->ReplaceInput(0, n13);
-  n14->ReplaceInput(1, n2);
-  n14->ReplaceInput(2, n7);
-  n14->ReplaceInput(3, n13);
-  n14->ReplaceInput(4, n10);
-  n15->ReplaceInput(0, n14);
-  op = common_builder.Parameter(0);
-  Node* n5 = graph.NewNode(op, n0);
-  USE(n5);
-  n15->ReplaceInput(1, n5);
-  n15->ReplaceInput(2, n7);
-  n15->ReplaceInput(3, n14);
-  n15->ReplaceInput(4, n10);
-  n16->ReplaceInput(0, n15);
-  n16->ReplaceInput(1, n15);
-  n16->ReplaceInput(2, n10);
-  n22->ReplaceInput(0, n16);
-  op = common_builder.Return();
-  Node* n21 = graph.NewNode(op, nil, nil, nil);
-  USE(n21);
-  op = js_builder.Subtract();
-  Node* n20 = graph.NewNode(op, nil, nil, nil, nil, nil);
-  USE(n20);
-  op = js_builder.Multiply();
-  Node* n19 = graph.NewNode(op, nil, nil, nil, nil, nil);
-  USE(n19);
-  n19->ReplaceInput(0, n4);
-  n19->ReplaceInput(1, n4);
-  n19->ReplaceInput(2, n7);
-  n19->ReplaceInput(3, n8);
-  op = common_builder.IfFalse();
-  Node* n18 = graph.NewNode(op, nil);
-  USE(n18);
-  n18->ReplaceInput(0, n9);
-  n19->ReplaceInput(4, n18);
-  n20->ReplaceInput(0, n19);
-  n20->ReplaceInput(1, n2);
-  n20->ReplaceInput(2, n7);
-  n20->ReplaceInput(3, n19);
-  n20->ReplaceInput(4, n18);
-  n21->ReplaceInput(0, n20);
-  n21->ReplaceInput(1, n20);
-  n21->ReplaceInput(2, n18);
-  n22->ReplaceInput(1, n21);
-  n23->ReplaceInput(0, n22);
-
-  graph.SetStart(n0);
-  graph.SetEnd(n23);
-
-  ComputeAndVerifySchedule(20, &graph);
-}
-
-
-TEST(BuildScheduleSimpleLoop) {
-  HandleAndZoneScope scope;
-  Isolate* isolate = scope.main_isolate();
-  Graph graph(scope.main_zone());
-  CommonOperatorBuilder common_builder(scope.main_zone());
-  JSOperatorBuilder js_builder(scope.main_zone());
-  const Operator* op;
-
-  Handle<HeapObject> object =
-      Handle<HeapObject>(isolate->heap()->undefined_value(), isolate);
-  Unique<HeapObject> unique_constant =
-      Unique<HeapObject>::CreateUninitialized(object);
-
-  // Manually transcripted code for:
-  // function turbo_fan_test(a, b) {
-  //   while (a < b) {
-  //     a++;
-  //   }
-  //   return a;
-  // }
-  op = common_builder.Start(0);
-  Node* n0 = graph.NewNode(op);
-  USE(n0);
-  Node* nil = graph.NewNode(common_builder.Dead());
-  op = common_builder.End();
-  Node* n20 = graph.NewNode(op, nil);
-  USE(n20);
-  op = common_builder.Return();
-  Node* n19 = graph.NewNode(op, nil, nil, nil);
-  USE(n19);
-  op = common_builder.Phi(kMachAnyTagged, 2);
-  Node* n8 = graph.NewNode(op, nil, nil, nil);
-  USE(n8);
-  op = common_builder.Parameter(0);
-  Node* n2 = graph.NewNode(op, n0);
-  USE(n2);
-  n8->ReplaceInput(0, n2);
-  op = js_builder.Add();
-  Node* n18 = graph.NewNode(op, nil, nil, nil, nil, nil);
-  USE(n18);
-  op = js_builder.ToNumber();
-  Node* n16 = graph.NewNode(op, nil, nil, nil, nil);
-  USE(n16);
-  n16->ReplaceInput(0, n8);
-  op = common_builder.HeapConstant(unique_constant);
-  Node* n5 = graph.NewNode(op);
-  USE(n5);
-  n16->ReplaceInput(1, n5);
-  op = js_builder.LessThan();
-  Node* n12 = graph.NewNode(op, nil, nil, nil, nil, nil);
-  USE(n12);
-  n12->ReplaceInput(0, n8);
-  op = common_builder.Phi(kMachAnyTagged, 2);
-  Node* n9 = graph.NewNode(op, nil, nil, nil);
-  USE(n9);
-  op = common_builder.Parameter(0);
-  Node* n3 = graph.NewNode(op, n0);
-  USE(n3);
-  n9->ReplaceInput(0, n3);
-  n9->ReplaceInput(1, n9);
-  op = common_builder.Loop(2);
-  Node* n6 = graph.NewNode(op, nil, nil);
-  USE(n6);
-  n6->ReplaceInput(0, n0);
-  op = common_builder.IfTrue();
-  Node* n14 = graph.NewNode(op, nil);
-  USE(n14);
-  op = common_builder.Branch();
-  Node* n13 = graph.NewNode(op, nil, nil);
-  USE(n13);
-  n13->ReplaceInput(0, n12);
-  n13->ReplaceInput(1, n6);
-  n14->ReplaceInput(0, n13);
-  n6->ReplaceInput(1, n14);
-  n9->ReplaceInput(2, n6);
-  n12->ReplaceInput(1, n9);
-  n12->ReplaceInput(2, n5);
-  op = common_builder.Phi(kMachAnyTagged, 2);
-  Node* n10 = graph.NewNode(op, nil, nil, nil);
-  USE(n10);
-  n10->ReplaceInput(0, n0);
-  n10->ReplaceInput(1, n18);
-  n10->ReplaceInput(2, n6);
-  n12->ReplaceInput(3, n10);
-  n12->ReplaceInput(4, n6);
-  n16->ReplaceInput(2, n12);
-  n16->ReplaceInput(3, n14);
-  n18->ReplaceInput(0, n16);
-  op = common_builder.NumberConstant(0);
-  Node* n17 = graph.NewNode(op);
-  USE(n17);
-  n18->ReplaceInput(1, n17);
-  n18->ReplaceInput(2, n5);
-  n18->ReplaceInput(3, n16);
-  n18->ReplaceInput(4, n14);
-  n8->ReplaceInput(1, n18);
-  n8->ReplaceInput(2, n6);
-  n19->ReplaceInput(0, n8);
-  n19->ReplaceInput(1, n12);
-  op = common_builder.IfFalse();
-  Node* n15 = graph.NewNode(op, nil);
-  USE(n15);
-  n15->ReplaceInput(0, n13);
-  n19->ReplaceInput(2, n15);
-  n20->ReplaceInput(0, n19);
-
-  graph.SetStart(n0);
-  graph.SetEnd(n20);
-
-  ComputeAndVerifySchedule(19, &graph);
-}
-
-
-TEST(BuildScheduleComplexLoops) {
-  HandleAndZoneScope scope;
-  Isolate* isolate = scope.main_isolate();
-  Graph graph(scope.main_zone());
-  CommonOperatorBuilder common_builder(scope.main_zone());
-  JSOperatorBuilder js_builder(scope.main_zone());
-  const Operator* op;
-
-  Handle<HeapObject> object =
-      Handle<HeapObject>(isolate->heap()->undefined_value(), isolate);
-  Unique<HeapObject> unique_constant =
-      Unique<HeapObject>::CreateUninitialized(object);
-
-  // Manually transcripted code for:
-  // function turbo_fan_test(a, b, c) {
-  //   while (a < b) {
-  //     a++;
-  //     while (c < b) {
-  //       c++;
-  //     }
-  //   }
-  //   while (a < b) {
-  //     a += 2;
-  //   }
-  //   return a;
-  // }
-  op = common_builder.Start(0);
-  Node* n0 = graph.NewNode(op);
-  USE(n0);
-  Node* nil = graph.NewNode(common_builder.Dead());
-  op = common_builder.End();
-  Node* n46 = graph.NewNode(op, nil);
-  USE(n46);
-  op = common_builder.Return();
-  Node* n45 = graph.NewNode(op, nil, nil, nil);
-  USE(n45);
-  op = common_builder.Phi(kMachAnyTagged, 2);
-  Node* n35 = graph.NewNode(op, nil, nil, nil);
-  USE(n35);
-  op = common_builder.Phi(kMachAnyTagged, 2);
-  Node* n9 = graph.NewNode(op, nil, nil, nil);
-  USE(n9);
-  op = common_builder.Parameter(0);
-  Node* n2 = graph.NewNode(op, n0);
-  USE(n2);
-  n9->ReplaceInput(0, n2);
-  op = common_builder.Phi(kMachAnyTagged, 2);
-  Node* n23 = graph.NewNode(op, nil, nil, nil);
-  USE(n23);
-  op = js_builder.Add();
-  Node* n20 = graph.NewNode(op, nil, nil, nil, nil, nil);
-  USE(n20);
-  op = js_builder.ToNumber();
-  Node* n18 = graph.NewNode(op, nil, nil, nil, nil);
-  USE(n18);
-  n18->ReplaceInput(0, n9);
-  op = common_builder.HeapConstant(unique_constant);
-  Node* n6 = graph.NewNode(op);
-  USE(n6);
-  n18->ReplaceInput(1, n6);
-  op = js_builder.LessThan();
-  Node* n14 = graph.NewNode(op, nil, nil, nil, nil, nil);
-  USE(n14);
-  n14->ReplaceInput(0, n9);
-  op = common_builder.Phi(kMachAnyTagged, 2);
-  Node* n10 = graph.NewNode(op, nil, nil, nil);
-  USE(n10);
-  op = common_builder.Parameter(0);
-  Node* n3 = graph.NewNode(op, n0);
-  USE(n3);
-  n10->ReplaceInput(0, n3);
-  op = common_builder.Phi(kMachAnyTagged, 2);
-  Node* n24 = graph.NewNode(op, nil, nil, nil);
-  USE(n24);
-  n24->ReplaceInput(0, n10);
-  n24->ReplaceInput(1, n24);
-  op = common_builder.Loop(2);
-  Node* n21 = graph.NewNode(op, nil, nil);
-  USE(n21);
-  op = common_builder.IfTrue();
-  Node* n16 = graph.NewNode(op, nil);
-  USE(n16);
-  op = common_builder.Branch();
-  Node* n15 = graph.NewNode(op, nil, nil);
-  USE(n15);
-  n15->ReplaceInput(0, n14);
-  op = common_builder.Loop(2);
-  Node* n7 = graph.NewNode(op, nil, nil);
-  USE(n7);
-  n7->ReplaceInput(0, n0);
-  op = common_builder.IfFalse();
-  Node* n30 = graph.NewNode(op, nil);
-  USE(n30);
-  op = common_builder.Branch();
-  Node* n28 = graph.NewNode(op, nil, nil);
-  USE(n28);
-  op = js_builder.LessThan();
-  Node* n27 = graph.NewNode(op, nil, nil, nil, nil, nil);
-  USE(n27);
-  op = common_builder.Phi(kMachAnyTagged, 2);
-  Node* n25 = graph.NewNode(op, nil, nil, nil);
-  USE(n25);
-  op = common_builder.Phi(kMachAnyTagged, 2);
-  Node* n11 = graph.NewNode(op, nil, nil, nil);
-  USE(n11);
-  op = common_builder.Parameter(0);
-  Node* n4 = graph.NewNode(op, n0);
-  USE(n4);
-  n11->ReplaceInput(0, n4);
-  n11->ReplaceInput(1, n25);
-  n11->ReplaceInput(2, n7);
-  n25->ReplaceInput(0, n11);
-  op = js_builder.Add();
-  Node* n32 = graph.NewNode(op, nil, nil, nil, nil, nil);
-  USE(n32);
-  op = js_builder.ToNumber();
-  Node* n31 = graph.NewNode(op, nil, nil, nil, nil);
-  USE(n31);
-  n31->ReplaceInput(0, n25);
-  n31->ReplaceInput(1, n6);
-  n31->ReplaceInput(2, n27);
-  op = common_builder.IfTrue();
-  Node* n29 = graph.NewNode(op, nil);
-  USE(n29);
-  n29->ReplaceInput(0, n28);
-  n31->ReplaceInput(3, n29);
-  n32->ReplaceInput(0, n31);
-  op = common_builder.NumberConstant(0);
-  Node* n19 = graph.NewNode(op);
-  USE(n19);
-  n32->ReplaceInput(1, n19);
-  n32->ReplaceInput(2, n6);
-  n32->ReplaceInput(3, n31);
-  n32->ReplaceInput(4, n29);
-  n25->ReplaceInput(1, n32);
-  n25->ReplaceInput(2, n21);
-  n27->ReplaceInput(0, n25);
-  n27->ReplaceInput(1, n24);
-  n27->ReplaceInput(2, n6);
-  op = common_builder.Phi(kMachAnyTagged, 2);
-  Node* n26 = graph.NewNode(op, nil, nil, nil);
-  USE(n26);
-  n26->ReplaceInput(0, n20);
-  n26->ReplaceInput(1, n32);
-  n26->ReplaceInput(2, n21);
-  n27->ReplaceInput(3, n26);
-  n27->ReplaceInput(4, n21);
-  n28->ReplaceInput(0, n27);
-  n28->ReplaceInput(1, n21);
-  n30->ReplaceInput(0, n28);
-  n7->ReplaceInput(1, n30);
-  n15->ReplaceInput(1, n7);
-  n16->ReplaceInput(0, n15);
-  n21->ReplaceInput(0, n16);
-  n21->ReplaceInput(1, n29);
-  n24->ReplaceInput(2, n21);
-  n10->ReplaceInput(1, n24);
-  n10->ReplaceInput(2, n7);
-  n14->ReplaceInput(1, n10);
-  n14->ReplaceInput(2, n6);
-  op = common_builder.Phi(kMachAnyTagged, 2);
-  Node* n12 = graph.NewNode(op, nil, nil, nil);
-  USE(n12);
-  n12->ReplaceInput(0, n0);
-  n12->ReplaceInput(1, n27);
-  n12->ReplaceInput(2, n7);
-  n14->ReplaceInput(3, n12);
-  n14->ReplaceInput(4, n7);
-  n18->ReplaceInput(2, n14);
-  n18->ReplaceInput(3, n16);
-  n20->ReplaceInput(0, n18);
-  n20->ReplaceInput(1, n19);
-  n20->ReplaceInput(2, n6);
-  n20->ReplaceInput(3, n18);
-  n20->ReplaceInput(4, n16);
-  n23->ReplaceInput(0, n20);
-  n23->ReplaceInput(1, n23);
-  n23->ReplaceInput(2, n21);
-  n9->ReplaceInput(1, n23);
-  n9->ReplaceInput(2, n7);
-  n35->ReplaceInput(0, n9);
-  op = js_builder.Add();
-  Node* n44 = graph.NewNode(op, nil, nil, nil, nil, nil);
-  USE(n44);
-  n44->ReplaceInput(0, n35);
-  op = common_builder.NumberConstant(0);
-  Node* n43 = graph.NewNode(op);
-  USE(n43);
-  n44->ReplaceInput(1, n43);
-  n44->ReplaceInput(2, n6);
-  op = js_builder.LessThan();
-  Node* n39 = graph.NewNode(op, nil, nil, nil, nil, nil);
-  USE(n39);
-  n39->ReplaceInput(0, n35);
-  op = common_builder.Phi(kMachAnyTagged, 2);
-  Node* n36 = graph.NewNode(op, nil, nil, nil);
-  USE(n36);
-  n36->ReplaceInput(0, n10);
-  n36->ReplaceInput(1, n36);
-  op = common_builder.Loop(2);
-  Node* n33 = graph.NewNode(op, nil, nil);
-  USE(n33);
-  op = common_builder.IfFalse();
-  Node* n17 = graph.NewNode(op, nil);
-  USE(n17);
-  n17->ReplaceInput(0, n15);
-  n33->ReplaceInput(0, n17);
-  op = common_builder.IfTrue();
-  Node* n41 = graph.NewNode(op, nil);
-  USE(n41);
-  op = common_builder.Branch();
-  Node* n40 = graph.NewNode(op, nil, nil);
-  USE(n40);
-  n40->ReplaceInput(0, n39);
-  n40->ReplaceInput(1, n33);
-  n41->ReplaceInput(0, n40);
-  n33->ReplaceInput(1, n41);
-  n36->ReplaceInput(2, n33);
-  n39->ReplaceInput(1, n36);
-  n39->ReplaceInput(2, n6);
-  op = common_builder.Phi(kMachAnyTagged, 2);
-  Node* n38 = graph.NewNode(op, nil, nil, nil);
-  USE(n38);
-  n38->ReplaceInput(0, n14);
-  n38->ReplaceInput(1, n44);
-  n38->ReplaceInput(2, n33);
-  n39->ReplaceInput(3, n38);
-  n39->ReplaceInput(4, n33);
-  n44->ReplaceInput(3, n39);
-  n44->ReplaceInput(4, n41);
-  n35->ReplaceInput(1, n44);
-  n35->ReplaceInput(2, n33);
-  n45->ReplaceInput(0, n35);
-  n45->ReplaceInput(1, n39);
-  op = common_builder.IfFalse();
-  Node* n42 = graph.NewNode(op, nil);
-  USE(n42);
-  n42->ReplaceInput(0, n40);
-  n45->ReplaceInput(2, n42);
-  n46->ReplaceInput(0, n45);
-
-  graph.SetStart(n0);
-  graph.SetEnd(n46);
-
-  ComputeAndVerifySchedule(46, &graph);
-}
-
-
-TEST(BuildScheduleBreakAndContinue) {
-  HandleAndZoneScope scope;
-  Isolate* isolate = scope.main_isolate();
-  Graph graph(scope.main_zone());
-  CommonOperatorBuilder common_builder(scope.main_zone());
-  JSOperatorBuilder js_builder(scope.main_zone());
-  const Operator* op;
-
-  Handle<HeapObject> object =
-      Handle<HeapObject>(isolate->heap()->undefined_value(), isolate);
-  Unique<HeapObject> unique_constant =
-      Unique<HeapObject>::CreateUninitialized(object);
-
-  // Manually transcripted code for:
-  // function turbo_fan_test(a, b, c) {
-  //   var d = 0;
-  //   while (a < b) {
-  //     a++;
-  //     while (c < b) {
-  //       c++;
-  //       if (d == 0) break;
-  //       a++;
-  //     }
-  //     if (a == 1) continue;
-  //     d++;
-  //   }
-  //   return a + d;
-  // }
-  op = common_builder.Start(0);
-  Node* n0 = graph.NewNode(op);
-  USE(n0);
-  Node* nil = graph.NewNode(common_builder.Dead());
-  op = common_builder.End();
-  Node* n58 = graph.NewNode(op, nil);
-  USE(n58);
-  op = common_builder.Return();
-  Node* n57 = graph.NewNode(op, nil, nil, nil);
-  USE(n57);
-  op = js_builder.Add();
-  Node* n56 = graph.NewNode(op, nil, nil, nil, nil, nil);
-  USE(n56);
-  op = common_builder.Phi(kMachAnyTagged, 2);
-  Node* n10 = graph.NewNode(op, nil, nil, nil);
-  USE(n10);
-  op = common_builder.Parameter(0);
-  Node* n2 = graph.NewNode(op, n0);
-  USE(n2);
-  n10->ReplaceInput(0, n2);
-  op = common_builder.Phi(kMachAnyTagged, 2);
-  Node* n25 = graph.NewNode(op, nil, nil, nil);
-  USE(n25);
-  op = js_builder.Add();
-  Node* n22 = graph.NewNode(op, nil, nil, nil, nil, nil);
-  USE(n22);
-  op = js_builder.ToNumber();
-  Node* n20 = graph.NewNode(op, nil, nil, nil, nil);
-  USE(n20);
-  n20->ReplaceInput(0, n10);
-  op = common_builder.HeapConstant(unique_constant);
-  Node* n6 = graph.NewNode(op);
-  USE(n6);
-  n20->ReplaceInput(1, n6);
-  op = js_builder.LessThan();
-  Node* n16 = graph.NewNode(op, nil, nil, nil, nil, nil);
-  USE(n16);
-  n16->ReplaceInput(0, n10);
-  op = common_builder.Phi(kMachAnyTagged, 2);
-  Node* n11 = graph.NewNode(op, nil, nil, nil);
-  USE(n11);
-  op = common_builder.Parameter(0);
-  Node* n3 = graph.NewNode(op, n0);
-  USE(n3);
-  n11->ReplaceInput(0, n3);
-  op = common_builder.Phi(kMachAnyTagged, 2);
-  Node* n26 = graph.NewNode(op, nil, nil, nil);
-  USE(n26);
-  n26->ReplaceInput(0, n11);
-  n26->ReplaceInput(1, n26);
-  op = common_builder.Loop(2);
-  Node* n23 = graph.NewNode(op, nil, nil);
-  USE(n23);
-  op = common_builder.IfTrue();
-  Node* n18 = graph.NewNode(op, nil);
-  USE(n18);
-  op = common_builder.Branch();
-  Node* n17 = graph.NewNode(op, nil, nil);
-  USE(n17);
-  n17->ReplaceInput(0, n16);
-  op = common_builder.Loop(2);
-  Node* n8 = graph.NewNode(op, nil, nil);
-  USE(n8);
-  n8->ReplaceInput(0, n0);
-  op = common_builder.Merge(2);
-  Node* n53 = graph.NewNode(op, nil, nil);
-  USE(n53);
-  op = common_builder.IfTrue();
-  Node* n49 = graph.NewNode(op, nil);
-  USE(n49);
-  op = common_builder.Branch();
-  Node* n48 = graph.NewNode(op, nil, nil);
-  USE(n48);
-  op = js_builder.Equal();
-  Node* n47 = graph.NewNode(op, nil, nil, nil, nil, nil);
-  USE(n47);
-  n47->ReplaceInput(0, n25);
-  op = common_builder.NumberConstant(0);
-  Node* n46 = graph.NewNode(op);
-  USE(n46);
-  n47->ReplaceInput(1, n46);
-  n47->ReplaceInput(2, n6);
-  op = common_builder.Phi(kMachAnyTagged, 2);
-  Node* n42 = graph.NewNode(op, nil, nil, nil);
-  USE(n42);
-  op = js_builder.LessThan();
-  Node* n30 = graph.NewNode(op, nil, nil, nil, nil, nil);
-  USE(n30);
-  op = common_builder.Phi(kMachAnyTagged, 2);
-  Node* n27 = graph.NewNode(op, nil, nil, nil);
-  USE(n27);
-  op = common_builder.Phi(kMachAnyTagged, 2);
-  Node* n12 = graph.NewNode(op, nil, nil, nil);
-  USE(n12);
-  op = common_builder.Parameter(0);
-  Node* n4 = graph.NewNode(op, n0);
-  USE(n4);
-  n12->ReplaceInput(0, n4);
-  op = common_builder.Phi(kMachAnyTagged, 2);
-  Node* n41 = graph.NewNode(op, nil, nil, nil);
-  USE(n41);
-  n41->ReplaceInput(0, n27);
-  op = js_builder.Add();
-  Node* n35 = graph.NewNode(op, nil, nil, nil, nil, nil);
-  USE(n35);
-  op = js_builder.ToNumber();
-  Node* n34 = graph.NewNode(op, nil, nil, nil, nil);
-  USE(n34);
-  n34->ReplaceInput(0, n27);
-  n34->ReplaceInput(1, n6);
-  n34->ReplaceInput(2, n30);
-  op = common_builder.IfTrue();
-  Node* n32 = graph.NewNode(op, nil);
-  USE(n32);
-  op = common_builder.Branch();
-  Node* n31 = graph.NewNode(op, nil, nil);
-  USE(n31);
-  n31->ReplaceInput(0, n30);
-  n31->ReplaceInput(1, n23);
-  n32->ReplaceInput(0, n31);
-  n34->ReplaceInput(3, n32);
-  n35->ReplaceInput(0, n34);
-  op = common_builder.NumberConstant(0);
-  Node* n21 = graph.NewNode(op);
-  USE(n21);
-  n35->ReplaceInput(1, n21);
-  n35->ReplaceInput(2, n6);
-  n35->ReplaceInput(3, n34);
-  n35->ReplaceInput(4, n32);
-  n41->ReplaceInput(1, n35);
-  op = common_builder.Merge(2);
-  Node* n40 = graph.NewNode(op, nil, nil);
-  USE(n40);
-  op = common_builder.IfFalse();
-  Node* n33 = graph.NewNode(op, nil);
-  USE(n33);
-  n33->ReplaceInput(0, n31);
-  n40->ReplaceInput(0, n33);
-  op = common_builder.IfTrue();
-  Node* n39 = graph.NewNode(op, nil);
-  USE(n39);
-  op = common_builder.Branch();
-  Node* n38 = graph.NewNode(op, nil, nil);
-  USE(n38);
-  op = js_builder.Equal();
-  Node* n37 = graph.NewNode(op, nil, nil, nil, nil, nil);
-  USE(n37);
-  op = common_builder.Phi(kMachAnyTagged, 2);
-  Node* n28 = graph.NewNode(op, nil, nil, nil);
-  USE(n28);
-  op = common_builder.Phi(kMachAnyTagged, 2);
-  Node* n13 = graph.NewNode(op, nil, nil, nil);
-  USE(n13);
-  op = common_builder.NumberConstant(0);
-  Node* n7 = graph.NewNode(op);
-  USE(n7);
-  n13->ReplaceInput(0, n7);
-  op = common_builder.Phi(kMachAnyTagged, 2);
-  Node* n54 = graph.NewNode(op, nil, nil, nil);
-  USE(n54);
-  n54->ReplaceInput(0, n28);
-  op = js_builder.Add();
-  Node* n52 = graph.NewNode(op, nil, nil, nil, nil, nil);
-  USE(n52);
-  op = js_builder.ToNumber();
-  Node* n51 = graph.NewNode(op, nil, nil, nil, nil);
-  USE(n51);
-  n51->ReplaceInput(0, n28);
-  n51->ReplaceInput(1, n6);
-  n51->ReplaceInput(2, n47);
-  op = common_builder.IfFalse();
-  Node* n50 = graph.NewNode(op, nil);
-  USE(n50);
-  n50->ReplaceInput(0, n48);
-  n51->ReplaceInput(3, n50);
-  n52->ReplaceInput(0, n51);
-  n52->ReplaceInput(1, n21);
-  n52->ReplaceInput(2, n6);
-  n52->ReplaceInput(3, n51);
-  n52->ReplaceInput(4, n50);
-  n54->ReplaceInput(1, n52);
-  n54->ReplaceInput(2, n53);
-  n13->ReplaceInput(1, n54);
-  n13->ReplaceInput(2, n8);
-  n28->ReplaceInput(0, n13);
-  n28->ReplaceInput(1, n28);
-  n28->ReplaceInput(2, n23);
-  n37->ReplaceInput(0, n28);
-  op = common_builder.NumberConstant(0);
-  Node* n36 = graph.NewNode(op);
-  USE(n36);
-  n37->ReplaceInput(1, n36);
-  n37->ReplaceInput(2, n6);
-  n37->ReplaceInput(3, n35);
-  n37->ReplaceInput(4, n32);
-  n38->ReplaceInput(0, n37);
-  n38->ReplaceInput(1, n32);
-  n39->ReplaceInput(0, n38);
-  n40->ReplaceInput(1, n39);
-  n41->ReplaceInput(2, n40);
-  n12->ReplaceInput(1, n41);
-  n12->ReplaceInput(2, n8);
-  n27->ReplaceInput(0, n12);
-  n27->ReplaceInput(1, n35);
-  n27->ReplaceInput(2, n23);
-  n30->ReplaceInput(0, n27);
-  n30->ReplaceInput(1, n26);
-  n30->ReplaceInput(2, n6);
-  op = common_builder.Phi(kMachAnyTagged, 2);
-  Node* n29 = graph.NewNode(op, nil, nil, nil);
-  USE(n29);
-  n29->ReplaceInput(0, n22);
-  op = js_builder.Add();
-  Node* n45 = graph.NewNode(op, nil, nil, nil, nil, nil);
-  USE(n45);
-  op = js_builder.ToNumber();
-  Node* n44 = graph.NewNode(op, nil, nil, nil, nil);
-  USE(n44);
-  n44->ReplaceInput(0, n25);
-  n44->ReplaceInput(1, n6);
-  n44->ReplaceInput(2, n37);
-  op = common_builder.IfFalse();
-  Node* n43 = graph.NewNode(op, nil);
-  USE(n43);
-  n43->ReplaceInput(0, n38);
-  n44->ReplaceInput(3, n43);
-  n45->ReplaceInput(0, n44);
-  n45->ReplaceInput(1, n21);
-  n45->ReplaceInput(2, n6);
-  n45->ReplaceInput(3, n44);
-  n45->ReplaceInput(4, n43);
-  n29->ReplaceInput(1, n45);
-  n29->ReplaceInput(2, n23);
-  n30->ReplaceInput(3, n29);
-  n30->ReplaceInput(4, n23);
-  n42->ReplaceInput(0, n30);
-  n42->ReplaceInput(1, n37);
-  n42->ReplaceInput(2, n40);
-  n47->ReplaceInput(3, n42);
-  n47->ReplaceInput(4, n40);
-  n48->ReplaceInput(0, n47);
-  n48->ReplaceInput(1, n40);
-  n49->ReplaceInput(0, n48);
-  n53->ReplaceInput(0, n49);
-  n53->ReplaceInput(1, n50);
-  n8->ReplaceInput(1, n53);
-  n17->ReplaceInput(1, n8);
-  n18->ReplaceInput(0, n17);
-  n23->ReplaceInput(0, n18);
-  n23->ReplaceInput(1, n43);
-  n26->ReplaceInput(2, n23);
-  n11->ReplaceInput(1, n26);
-  n11->ReplaceInput(2, n8);
-  n16->ReplaceInput(1, n11);
-  n16->ReplaceInput(2, n6);
-  op = common_builder.Phi(kMachAnyTagged, 2);
-  Node* n14 = graph.NewNode(op, nil, nil, nil);
-  USE(n14);
-  n14->ReplaceInput(0, n0);
-  op = common_builder.Phi(kMachAnyTagged, 2);
-  Node* n55 = graph.NewNode(op, nil, nil, nil);
-  USE(n55);
-  n55->ReplaceInput(0, n47);
-  n55->ReplaceInput(1, n52);
-  n55->ReplaceInput(2, n53);
-  n14->ReplaceInput(1, n55);
-  n14->ReplaceInput(2, n8);
-  n16->ReplaceInput(3, n14);
-  n16->ReplaceInput(4, n8);
-  n20->ReplaceInput(2, n16);
-  n20->ReplaceInput(3, n18);
-  n22->ReplaceInput(0, n20);
-  n22->ReplaceInput(1, n21);
-  n22->ReplaceInput(2, n6);
-  n22->ReplaceInput(3, n20);
-  n22->ReplaceInput(4, n18);
-  n25->ReplaceInput(0, n22);
-  n25->ReplaceInput(1, n45);
-  n25->ReplaceInput(2, n23);
-  n10->ReplaceInput(1, n25);
-  n10->ReplaceInput(2, n8);
-  n56->ReplaceInput(0, n10);
-  n56->ReplaceInput(1, n13);
-  n56->ReplaceInput(2, n6);
-  n56->ReplaceInput(3, n16);
-  op = common_builder.IfFalse();
-  Node* n19 = graph.NewNode(op, nil);
-  USE(n19);
-  n19->ReplaceInput(0, n17);
-  n56->ReplaceInput(4, n19);
-  n57->ReplaceInput(0, n56);
-  n57->ReplaceInput(1, n56);
-  n57->ReplaceInput(2, n19);
-  n58->ReplaceInput(0, n57);
-
-  graph.SetStart(n0);
-  graph.SetEnd(n58);
-
-  ComputeAndVerifySchedule(62, &graph);
-}
-
-
-TEST(BuildScheduleSimpleLoopWithCodeMotion) {
-  HandleAndZoneScope scope;
-  Isolate* isolate = scope.main_isolate();
-  Graph graph(scope.main_zone());
-  CommonOperatorBuilder common_builder(scope.main_zone());
-  JSOperatorBuilder js_builder(scope.main_zone());
-  const Operator* op;
-
-  Handle<HeapObject> object =
-      Handle<HeapObject>(isolate->heap()->undefined_value(), isolate);
-  Unique<HeapObject> unique_constant =
-      Unique<HeapObject>::CreateUninitialized(object);
-
-  // Manually transcripted code for:
-  // function turbo_fan_test(a, b, c) {
-  //   while (a < b) {
-  //     a += b + c;
-  //   }
-  //   return a;
-  // }
-  op = common_builder.Start(0);
-  Node* n0 = graph.NewNode(op);
-  USE(n0);
-  Node* nil = graph.NewNode(common_builder.Dead());
-  op = common_builder.End();
-  Node* n22 = graph.NewNode(op, nil);
-  USE(n22);
-  op = common_builder.Return();
-  Node* n21 = graph.NewNode(op, nil, nil, nil);
-  USE(n21);
-  op = common_builder.Phi(kMachAnyTagged, 2);
-  Node* n9 = graph.NewNode(op, nil, nil, nil);
-  USE(n9);
-  op = common_builder.Parameter(0);
-  Node* n2 = graph.NewNode(op, n0);
-  USE(n2);
-  n9->ReplaceInput(0, n2);
-  op = js_builder.Add();
-  Node* n20 = graph.NewNode(op, nil, nil, nil, nil, nil);
-  USE(n20);
-  n20->ReplaceInput(0, n9);
-  op = &kIntAdd;
-  Node* n19 = graph.NewNode(op, nil, nil);
-  USE(n19);
-  op = common_builder.Phi(kMachAnyTagged, 2);
-  Node* n10 = graph.NewNode(op, nil, nil, nil);
-  USE(n10);
-  op = common_builder.Parameter(0);
-  Node* n3 = graph.NewNode(op, n0);
-  USE(n3);
-  n10->ReplaceInput(0, n3);
-  n10->ReplaceInput(1, n10);
-  op = common_builder.Loop(2);
-  Node* n7 = graph.NewNode(op, nil, nil);
-  USE(n7);
-  n7->ReplaceInput(0, n0);
-  op = common_builder.IfTrue();
-  Node* n17 = graph.NewNode(op, nil);
-  USE(n17);
-  op = common_builder.Branch();
-  Node* n16 = graph.NewNode(op, nil, nil);
-  USE(n16);
-  op = js_builder.ToBoolean();
-  Node* n15 = graph.NewNode(op, nil, nil, nil, nil);
-  USE(n15);
-  op = js_builder.LessThan();
-  Node* n14 = graph.NewNode(op, nil, nil, nil, nil, nil);
-  USE(n14);
-  n14->ReplaceInput(0, n9);
-  n14->ReplaceInput(1, n10);
-  op = common_builder.HeapConstant(unique_constant);
-  Node* n6 = graph.NewNode(op);
-  USE(n6);
-  n14->ReplaceInput(2, n6);
-  op = common_builder.Phi(kMachAnyTagged, 2);
-  Node* n12 = graph.NewNode(op, nil, nil, nil);
-  USE(n12);
-  n12->ReplaceInput(0, n0);
-  n12->ReplaceInput(1, n20);
-  n12->ReplaceInput(2, n7);
-  n14->ReplaceInput(3, n12);
-  n14->ReplaceInput(4, n7);
-  n15->ReplaceInput(0, n14);
-  n15->ReplaceInput(1, n6);
-  n15->ReplaceInput(2, n14);
-  n15->ReplaceInput(3, n7);
-  n16->ReplaceInput(0, n15);
-  n16->ReplaceInput(1, n7);
-  n17->ReplaceInput(0, n16);
-  n7->ReplaceInput(1, n17);
-  n10->ReplaceInput(2, n7);
-  n19->ReplaceInput(0, n2);
-  op = common_builder.Phi(kMachAnyTagged, 2);
-  Node* n11 = graph.NewNode(op, nil, nil, nil);
-  USE(n11);
-  op = common_builder.Parameter(0);
-  Node* n4 = graph.NewNode(op, n0);
-  USE(n4);
-  n11->ReplaceInput(0, n4);
-  n11->ReplaceInput(1, n11);
-  n11->ReplaceInput(2, n7);
-  n19->ReplaceInput(1, n3);
-  n20->ReplaceInput(1, n19);
-  n20->ReplaceInput(2, n6);
-  n20->ReplaceInput(3, n19);
-  n20->ReplaceInput(4, n17);
-  n9->ReplaceInput(1, n20);
-  n9->ReplaceInput(2, n7);
-  n21->ReplaceInput(0, n9);
-  n21->ReplaceInput(1, n15);
-  op = common_builder.IfFalse();
-  Node* n18 = graph.NewNode(op, nil);
-  USE(n18);
-  n18->ReplaceInput(0, n16);
-  n21->ReplaceInput(2, n18);
-  n22->ReplaceInput(0, n21);
-
-  graph.SetStart(n0);
-  graph.SetEnd(n22);
-
-  Schedule* schedule = ComputeAndVerifySchedule(19, &graph);
-  // Make sure the integer-only add gets hoisted to a different block that the
-  // JSAdd.
-  CHECK(schedule->block(n19) != schedule->block(n20));
-}
-
-
-#if V8_TURBOFAN_TARGET
-
-static Node* CreateDiamond(Graph* graph, CommonOperatorBuilder* common,
-                           Node* cond) {
-  Node* tv = graph->NewNode(common->Int32Constant(6));
-  Node* fv = graph->NewNode(common->Int32Constant(7));
-  Node* br = graph->NewNode(common->Branch(), cond, graph->start());
-  Node* t = graph->NewNode(common->IfTrue(), br);
-  Node* f = graph->NewNode(common->IfFalse(), br);
-  Node* m = graph->NewNode(common->Merge(2), t, f);
-  Node* phi = graph->NewNode(common->Phi(kMachAnyTagged, 2), tv, fv, m);
-  return phi;
-}
-
-
-TEST(FloatingDiamond1) {
-  HandleAndZoneScope scope;
-  Graph graph(scope.main_zone());
-  CommonOperatorBuilder common(scope.main_zone());
-
-  Node* start = graph.NewNode(common.Start(1));
-  graph.SetStart(start);
-
-  Node* p0 = graph.NewNode(common.Parameter(0), start);
-  Node* d1 = CreateDiamond(&graph, &common, p0);
-  Node* ret = graph.NewNode(common.Return(), d1, start, start);
-  Node* end = graph.NewNode(common.End(), ret, start);
-
-  graph.SetEnd(end);
-
-  ComputeAndVerifySchedule(13, &graph);
-}
-
-
-TEST(FloatingDiamond2) {
-  HandleAndZoneScope scope;
-  Graph graph(scope.main_zone());
-  CommonOperatorBuilder common(scope.main_zone());
-
-  Node* start = graph.NewNode(common.Start(2));
-  graph.SetStart(start);
-
-  Node* p0 = graph.NewNode(common.Parameter(0), start);
-  Node* p1 = graph.NewNode(common.Parameter(1), start);
-  Node* d1 = CreateDiamond(&graph, &common, p0);
-  Node* d2 = CreateDiamond(&graph, &common, p1);
-  Node* add = graph.NewNode(&kIntAdd, d1, d2);
-  Node* ret = graph.NewNode(common.Return(), add, start, start);
-  Node* end = graph.NewNode(common.End(), ret, start);
-
-  graph.SetEnd(end);
-
-  ComputeAndVerifySchedule(24, &graph);
-}
-
-
-TEST(FloatingDiamond3) {
-  HandleAndZoneScope scope;
-  Graph graph(scope.main_zone());
-  CommonOperatorBuilder common(scope.main_zone());
-
-  Node* start = graph.NewNode(common.Start(2));
-  graph.SetStart(start);
-
-  Node* p0 = graph.NewNode(common.Parameter(0), start);
-  Node* p1 = graph.NewNode(common.Parameter(1), start);
-  Node* d1 = CreateDiamond(&graph, &common, p0);
-  Node* d2 = CreateDiamond(&graph, &common, p1);
-  Node* add = graph.NewNode(&kIntAdd, d1, d2);
-  Node* d3 = CreateDiamond(&graph, &common, add);
-  Node* ret = graph.NewNode(common.Return(), d3, start, start);
-  Node* end = graph.NewNode(common.End(), ret, start);
-
-  graph.SetEnd(end);
-
-  ComputeAndVerifySchedule(33, &graph);
-}
-
-
-TEST(NestedFloatingDiamonds) {
-  HandleAndZoneScope scope;
-  Graph graph(scope.main_zone());
-  CommonOperatorBuilder common(scope.main_zone());
-  SimplifiedOperatorBuilder simplified(scope.main_zone());
-
-  Node* start = graph.NewNode(common.Start(2));
-  graph.SetStart(start);
-
-  Node* p0 = graph.NewNode(common.Parameter(0), start);
-
-  Node* fv = graph.NewNode(common.Int32Constant(7));
-  Node* br = graph.NewNode(common.Branch(), p0, graph.start());
-  Node* t = graph.NewNode(common.IfTrue(), br);
-  Node* f = graph.NewNode(common.IfFalse(), br);
-
-  Node* map = graph.NewNode(
-      simplified.LoadElement(AccessBuilder::ForFixedArrayElement()), p0, p0, p0,
-      start, f);
-  Node* br1 = graph.NewNode(common.Branch(), map, graph.start());
-  Node* t1 = graph.NewNode(common.IfTrue(), br1);
-  Node* f1 = graph.NewNode(common.IfFalse(), br1);
-  Node* m1 = graph.NewNode(common.Merge(2), t1, f1);
-  Node* ttrue = graph.NewNode(common.Int32Constant(1));
-  Node* ffalse = graph.NewNode(common.Int32Constant(0));
-  Node* phi1 = graph.NewNode(common.Phi(kMachAnyTagged, 2), ttrue, ffalse, m1);
-
-
-  Node* m = graph.NewNode(common.Merge(2), t, f);
-  Node* phi = graph.NewNode(common.Phi(kMachAnyTagged, 2), fv, phi1, m);
-  Node* ephi1 = graph.NewNode(common.EffectPhi(2), start, map, m);
-
-  Node* ret = graph.NewNode(common.Return(), phi, ephi1, start);
-  Node* end = graph.NewNode(common.End(), ret, start);
-
-  graph.SetEnd(end);
-
-  ComputeAndVerifySchedule(23, &graph);
-}
-
-
-TEST(NestedFloatingDiamondWithChain) {
-  HandleAndZoneScope scope;
-  Graph graph(scope.main_zone());
-  CommonOperatorBuilder common(scope.main_zone());
-
-  Node* start = graph.NewNode(common.Start(2));
-  graph.SetStart(start);
-
-  Node* p0 = graph.NewNode(common.Parameter(0), start);
-  Node* p1 = graph.NewNode(common.Parameter(1), start);
-  Node* c = graph.NewNode(common.Int32Constant(7));
-
-  Node* brA1 = graph.NewNode(common.Branch(), p0, graph.start());
-  Node* tA1 = graph.NewNode(common.IfTrue(), brA1);
-  Node* fA1 = graph.NewNode(common.IfFalse(), brA1);
-  Node* mA1 = graph.NewNode(common.Merge(2), tA1, fA1);
-  Node* phiA1 = graph.NewNode(common.Phi(kMachAnyTagged, 2), p0, p1, mA1);
-
-  Node* brB1 = graph.NewNode(common.Branch(), p1, graph.start());
-  Node* tB1 = graph.NewNode(common.IfTrue(), brB1);
-  Node* fB1 = graph.NewNode(common.IfFalse(), brB1);
-  Node* mB1 = graph.NewNode(common.Merge(2), tB1, fB1);
-  Node* phiB1 = graph.NewNode(common.Phi(kMachAnyTagged, 2), p0, p1, mB1);
-
-  Node* brA2 = graph.NewNode(common.Branch(), phiB1, mA1);
-  Node* tA2 = graph.NewNode(common.IfTrue(), brA2);
-  Node* fA2 = graph.NewNode(common.IfFalse(), brA2);
-  Node* mA2 = graph.NewNode(common.Merge(2), tA2, fA2);
-  Node* phiA2 = graph.NewNode(common.Phi(kMachAnyTagged, 2), phiB1, c, mA2);
-
-  Node* brB2 = graph.NewNode(common.Branch(), phiA1, mB1);
-  Node* tB2 = graph.NewNode(common.IfTrue(), brB2);
-  Node* fB2 = graph.NewNode(common.IfFalse(), brB2);
-  Node* mB2 = graph.NewNode(common.Merge(2), tB2, fB2);
-  Node* phiB2 = graph.NewNode(common.Phi(kMachAnyTagged, 2), phiA1, c, mB2);
-
-  Node* add = graph.NewNode(&kIntAdd, phiA2, phiB2);
-  Node* ret = graph.NewNode(common.Return(), add, start, start);
-  Node* end = graph.NewNode(common.End(), ret, start);
-
-  graph.SetEnd(end);
-
-  ComputeAndVerifySchedule(35, &graph);
-}
-
-
-TEST(NestedFloatingDiamondWithLoop) {
-  HandleAndZoneScope scope;
-  Graph graph(scope.main_zone());
-  CommonOperatorBuilder common(scope.main_zone());
-
-  Node* start = graph.NewNode(common.Start(2));
-  graph.SetStart(start);
-
-  Node* p0 = graph.NewNode(common.Parameter(0), start);
-
-  Node* fv = graph.NewNode(common.Int32Constant(7));
-  Node* br = graph.NewNode(common.Branch(), p0, graph.start());
-  Node* t = graph.NewNode(common.IfTrue(), br);
-  Node* f = graph.NewNode(common.IfFalse(), br);
-
-  Node* loop = graph.NewNode(common.Loop(2), f, start);
-  Node* ind = graph.NewNode(common.Phi(kMachAnyTagged, 2), p0, p0, loop);
-
-  Node* add = graph.NewNode(&kIntAdd, ind, fv);
-  Node* br1 = graph.NewNode(common.Branch(), add, loop);
-  Node* t1 = graph.NewNode(common.IfTrue(), br1);
-  Node* f1 = graph.NewNode(common.IfFalse(), br1);
-
-  loop->ReplaceInput(1, t1);  // close loop.
-  ind->ReplaceInput(1, ind);  // close induction variable.
-
-  Node* m = graph.NewNode(common.Merge(2), t, f1);
-  Node* phi = graph.NewNode(common.Phi(kMachAnyTagged, 2), fv, ind, m);
-
-  Node* ret = graph.NewNode(common.Return(), phi, start, start);
-  Node* end = graph.NewNode(common.End(), ret, start);
-
-  graph.SetEnd(end);
-
-  ComputeAndVerifySchedule(20, &graph);
-}
-
-
-TEST(LoopedFloatingDiamond1) {
-  HandleAndZoneScope scope;
-  Graph graph(scope.main_zone());
-  CommonOperatorBuilder common(scope.main_zone());
-
-  Node* start = graph.NewNode(common.Start(2));
-  graph.SetStart(start);
-
-  Node* p0 = graph.NewNode(common.Parameter(0), start);
-
-  Node* c = graph.NewNode(common.Int32Constant(7));
-  Node* loop = graph.NewNode(common.Loop(2), start, start);
-  Node* ind = graph.NewNode(common.Phi(kMachAnyTagged, 2), p0, p0, loop);
-  Node* add = graph.NewNode(&kIntAdd, ind, c);
-
-  Node* br = graph.NewNode(common.Branch(), add, loop);
-  Node* t = graph.NewNode(common.IfTrue(), br);
-  Node* f = graph.NewNode(common.IfFalse(), br);
-
-  Node* br1 = graph.NewNode(common.Branch(), p0, graph.start());
-  Node* t1 = graph.NewNode(common.IfTrue(), br1);
-  Node* f1 = graph.NewNode(common.IfFalse(), br1);
-  Node* m1 = graph.NewNode(common.Merge(2), t1, f1);
-  Node* phi1 = graph.NewNode(common.Phi(kMachAnyTagged, 2), add, p0, m1);
-
-  loop->ReplaceInput(1, t);    // close loop.
-  ind->ReplaceInput(1, phi1);  // close induction variable.
-
-  Node* ret = graph.NewNode(common.Return(), ind, start, f);
-  Node* end = graph.NewNode(common.End(), ret, f);
-
-  graph.SetEnd(end);
-
-  ComputeAndVerifySchedule(20, &graph);
-}
-
-
-TEST(LoopedFloatingDiamond2) {
-  HandleAndZoneScope scope;
-  Graph graph(scope.main_zone());
-  CommonOperatorBuilder common(scope.main_zone());
-
-  Node* start = graph.NewNode(common.Start(2));
-  graph.SetStart(start);
-
-  Node* p0 = graph.NewNode(common.Parameter(0), start);
-
-  Node* c = graph.NewNode(common.Int32Constant(7));
-  Node* loop = graph.NewNode(common.Loop(2), start, start);
-  Node* ind = graph.NewNode(common.Phi(kMachAnyTagged, 2), p0, p0, loop);
-
-  Node* br1 = graph.NewNode(common.Branch(), p0, graph.start());
-  Node* t1 = graph.NewNode(common.IfTrue(), br1);
-  Node* f1 = graph.NewNode(common.IfFalse(), br1);
-  Node* m1 = graph.NewNode(common.Merge(2), t1, f1);
-  Node* phi1 = graph.NewNode(common.Phi(kMachAnyTagged, 2), c, ind, m1);
-
-  Node* add = graph.NewNode(&kIntAdd, ind, phi1);
-
-  Node* br = graph.NewNode(common.Branch(), add, loop);
-  Node* t = graph.NewNode(common.IfTrue(), br);
-  Node* f = graph.NewNode(common.IfFalse(), br);
-
-  loop->ReplaceInput(1, t);   // close loop.
-  ind->ReplaceInput(1, add);  // close induction variable.
-
-  Node* ret = graph.NewNode(common.Return(), ind, start, f);
-  Node* end = graph.NewNode(common.End(), ret, f);
-
-  graph.SetEnd(end);
-
-  ComputeAndVerifySchedule(20, &graph);
-}
-
-
-TEST(LoopedFloatingDiamond3) {
-  HandleAndZoneScope scope;
-  Graph graph(scope.main_zone());
-  CommonOperatorBuilder common(scope.main_zone());
-
-  Node* start = graph.NewNode(common.Start(2));
-  graph.SetStart(start);
-
-  Node* p0 = graph.NewNode(common.Parameter(0), start);
-
-  Node* c = graph.NewNode(common.Int32Constant(7));
-  Node* loop = graph.NewNode(common.Loop(2), start, start);
-  Node* ind = graph.NewNode(common.Phi(kMachAnyTagged, 2), p0, p0, loop);
-
-  Node* br1 = graph.NewNode(common.Branch(), p0, graph.start());
-  Node* t1 = graph.NewNode(common.IfTrue(), br1);
-  Node* f1 = graph.NewNode(common.IfFalse(), br1);
-
-  Node* loop1 = graph.NewNode(common.Loop(2), t1, start);
-  Node* ind1 = graph.NewNode(common.Phi(kMachAnyTagged, 2), p0, p0, loop);
-
-  Node* add1 = graph.NewNode(&kIntAdd, ind1, c);
-  Node* br2 = graph.NewNode(common.Branch(), add1, loop1);
-  Node* t2 = graph.NewNode(common.IfTrue(), br2);
-  Node* f2 = graph.NewNode(common.IfFalse(), br2);
-
-  loop1->ReplaceInput(1, t2);   // close inner loop.
-  ind1->ReplaceInput(1, ind1);  // close inner induction variable.
-
-  Node* m1 = graph.NewNode(common.Merge(2), f1, f2);
-  Node* phi1 = graph.NewNode(common.Phi(kMachAnyTagged, 2), c, ind1, m1);
-
-  Node* add = graph.NewNode(&kIntAdd, ind, phi1);
-
-  Node* br = graph.NewNode(common.Branch(), add, loop);
-  Node* t = graph.NewNode(common.IfTrue(), br);
-  Node* f = graph.NewNode(common.IfFalse(), br);
-
-  loop->ReplaceInput(1, t);   // close loop.
-  ind->ReplaceInput(1, add);  // close induction variable.
-
-  Node* ret = graph.NewNode(common.Return(), ind, start, f);
-  Node* end = graph.NewNode(common.End(), ret, f);
-
-  graph.SetEnd(end);
-
-  ComputeAndVerifySchedule(28, &graph);
-}
-
-
-TEST(PhisPushedDownToDifferentBranches) {
-  HandleAndZoneScope scope;
-  Graph graph(scope.main_zone());
-  CommonOperatorBuilder common(scope.main_zone());
-
-  Node* start = graph.NewNode(common.Start(2));
-  graph.SetStart(start);
-
-  Node* p0 = graph.NewNode(common.Parameter(0), start);
-  Node* p1 = graph.NewNode(common.Parameter(1), start);
-
-  Node* v1 = graph.NewNode(common.Int32Constant(1));
-  Node* v2 = graph.NewNode(common.Int32Constant(2));
-  Node* v3 = graph.NewNode(common.Int32Constant(3));
-  Node* v4 = graph.NewNode(common.Int32Constant(4));
-  Node* br = graph.NewNode(common.Branch(), p0, graph.start());
-  Node* t = graph.NewNode(common.IfTrue(), br);
-  Node* f = graph.NewNode(common.IfFalse(), br);
-  Node* m = graph.NewNode(common.Merge(2), t, f);
-  Node* phi = graph.NewNode(common.Phi(kMachAnyTagged, 2), v1, v2, m);
-  Node* phi2 = graph.NewNode(common.Phi(kMachAnyTagged, 2), v3, v4, m);
-
-  Node* br2 = graph.NewNode(common.Branch(), p1, graph.start());
-  Node* t2 = graph.NewNode(common.IfTrue(), br2);
-  Node* f2 = graph.NewNode(common.IfFalse(), br2);
-  Node* m2 = graph.NewNode(common.Merge(2), t2, f2);
-  Node* phi3 = graph.NewNode(common.Phi(kMachAnyTagged, 2), phi, phi2, m2);
-
-  Node* ret = graph.NewNode(common.Return(), phi3, start, start);
-  Node* end = graph.NewNode(common.End(), ret, start);
-
-  graph.SetEnd(end);
-
-  ComputeAndVerifySchedule(24, &graph);
-}
-
-
-TEST(BranchHintTrue) {
-  HandleAndZoneScope scope;
-  Graph graph(scope.main_zone());
-  CommonOperatorBuilder common(scope.main_zone());
-
-  Node* start = graph.NewNode(common.Start(1));
-  graph.SetStart(start);
-
-  Node* p0 = graph.NewNode(common.Parameter(0), start);
-  Node* tv = graph.NewNode(common.Int32Constant(6));
-  Node* fv = graph.NewNode(common.Int32Constant(7));
-  Node* br = graph.NewNode(common.Branch(BranchHint::kTrue), p0, start);
-  Node* t = graph.NewNode(common.IfTrue(), br);
-  Node* f = graph.NewNode(common.IfFalse(), br);
-  Node* m = graph.NewNode(common.Merge(2), t, f);
-  Node* phi = graph.NewNode(common.Phi(kMachAnyTagged, 2), tv, fv, m);
-  Node* ret = graph.NewNode(common.Return(), phi, start, start);
-  Node* end = graph.NewNode(common.End(), ret, start);
-
-  graph.SetEnd(end);
-
-  Schedule* schedule = ComputeAndVerifySchedule(13, &graph);
-  // Make sure the false block is marked as deferred.
-  CHECK(!schedule->block(t)->deferred());
-  CHECK(schedule->block(f)->deferred());
-}
-
-
-TEST(BranchHintFalse) {
-  HandleAndZoneScope scope;
-  Graph graph(scope.main_zone());
-  CommonOperatorBuilder common(scope.main_zone());
-
-  Node* start = graph.NewNode(common.Start(1));
-  graph.SetStart(start);
-
-  Node* p0 = graph.NewNode(common.Parameter(0), start);
-  Node* tv = graph.NewNode(common.Int32Constant(6));
-  Node* fv = graph.NewNode(common.Int32Constant(7));
-  Node* br = graph.NewNode(common.Branch(BranchHint::kFalse), p0, start);
-  Node* t = graph.NewNode(common.IfTrue(), br);
-  Node* f = graph.NewNode(common.IfFalse(), br);
-  Node* m = graph.NewNode(common.Merge(2), t, f);
-  Node* phi = graph.NewNode(common.Phi(kMachAnyTagged, 2), tv, fv, m);
-  Node* ret = graph.NewNode(common.Return(), phi, start, start);
-  Node* end = graph.NewNode(common.End(), ret, start);
-
-  graph.SetEnd(end);
-
-  Schedule* schedule = ComputeAndVerifySchedule(13, &graph);
-  // Make sure the true block is marked as deferred.
-  CHECK(schedule->block(t)->deferred());
-  CHECK(!schedule->block(f)->deferred());
-}
-
-
-TEST(ScheduleTerminate) {
-  HandleAndZoneScope scope;
-  Graph graph(scope.main_zone());
-  CommonOperatorBuilder common(scope.main_zone());
-
-  Node* start = graph.NewNode(common.Start(1));
-  graph.SetStart(start);
-
-  Node* loop = graph.NewNode(common.Loop(2), start, start);
-  loop->ReplaceInput(1, loop);  // self loop, NTL.
-
-  Node* effect = graph.NewNode(common.EffectPhi(1), start, loop);
-  effect->ReplaceInput(0, effect);
-
-  Node* terminate = graph.NewNode(common.Terminate(1), effect, loop);
-  Node* end = graph.NewNode(common.End(), terminate);
-
-  graph.SetEnd(end);
-
-  Schedule* schedule = ComputeAndVerifySchedule(6, &graph);
-  BasicBlock* block = schedule->block(loop);
-  CHECK_NE(NULL, loop);
-  CHECK_EQ(block, schedule->block(effect));
-  CHECK_GE(block->rpo_number(), 0);
-}
-
-#endif
diff --git a/test/cctest/compiler/test-simplified-lowering.cc b/test/cctest/compiler/test-simplified-lowering.cc
index 147aa32..1b752ed 100644
--- a/test/cctest/compiler/test-simplified-lowering.cc
+++ b/test/cctest/compiler/test-simplified-lowering.cc
@@ -4,46 +4,49 @@
 
 #include <limits>
 
+#include "src/ast/scopes.h"
 #include "src/compiler/access-builder.h"
 #include "src/compiler/change-lowering.h"
 #include "src/compiler/control-builders.h"
 #include "src/compiler/graph-reducer.h"
 #include "src/compiler/graph-visualizer.h"
-#include "src/compiler/node-properties-inl.h"
+#include "src/compiler/node-properties.h"
 #include "src/compiler/pipeline.h"
 #include "src/compiler/representation-change.h"
 #include "src/compiler/simplified-lowering.h"
+#include "src/compiler/source-position.h"
 #include "src/compiler/typer.h"
 #include "src/compiler/verifier.h"
 #include "src/execution.h"
-#include "src/parser.h"
-#include "src/rewriter.h"
-#include "src/scopes.h"
+#include "src/parsing/parser.h"
+#include "src/parsing/rewriter.h"
 #include "test/cctest/cctest.h"
 #include "test/cctest/compiler/codegen-tester.h"
+#include "test/cctest/compiler/function-tester.h"
 #include "test/cctest/compiler/graph-builder-tester.h"
 #include "test/cctest/compiler/value-helper.h"
 
-using namespace v8::internal;
-using namespace v8::internal::compiler;
+namespace v8 {
+namespace internal {
+namespace compiler {
 
 template <typename ReturnType>
 class SimplifiedLoweringTester : public GraphBuilderTester<ReturnType> {
  public:
-  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->graph(), MaybeHandle<Context>()),
+  SimplifiedLoweringTester(MachineType p0 = MachineType::None(),
+                           MachineType p1 = MachineType::None())
+      : GraphBuilderTester<ReturnType>(p0, p1),
+        typer(this->isolate(), this->graph()),
         javascript(this->zone()),
-        jsgraph(this->graph(), this->common(), &javascript, this->machine()),
-        lowering(&jsgraph, this->zone()) {}
+        jsgraph(this->isolate(), this->graph(), this->common(), &javascript,
+                this->simplified(), this->machine()),
+        source_positions(jsgraph.graph()),
+        lowering(&jsgraph, this->zone(), &source_positions) {}
 
   Typer typer;
   JSOperatorBuilder javascript;
   JSGraph jsgraph;
+  SourcePositionTable source_positions;
   SimplifiedLowering lowering;
 
   void LowerAllNodes() {
@@ -57,12 +60,8 @@
     typer.Run();
     lowering.LowerAllNodes();
 
-    Zone* zone = this->zone();
-    CompilationInfo info(zone->isolate(), zone);
-    Linkage linkage(
-        zone, Linkage::GetSimplifiedCDescriptor(zone, this->machine_sig_));
-    ChangeLowering lowering(&jsgraph, &linkage);
-    GraphReducer reducer(this->graph(), this->zone());
+    ChangeLowering lowering(&jsgraph);
+    GraphReducer reducer(this->zone(), this->graph());
     reducer.AddReducer(&lowering);
     reducer.ReduceGraph();
     Verifier::Run(this->graph());
@@ -77,6 +76,17 @@
     CHECK(factory()->NewNumber(expected)->SameValue(result));
   }
 
+  template <typename T>
+  T* CallWithPotentialGC() {
+    // TODO(titzer): we wrap the code in a JSFunction here to reuse the
+    // JSEntryStub; that could be done with a special prologue or other stub.
+    Handle<JSFunction> fun = FunctionTester::ForMachineGraph(this->graph(), 0);
+    Handle<Object>* args = NULL;
+    MaybeHandle<Object> result = Execution::Call(
+        this->isolate(), fun, factory()->undefined_value(), 0, args);
+    return T::cast(*result.ToHandleChecked());
+  }
+
   Factory* factory() { return this->isolate()->factory(); }
   Heap* heap() { return this->isolate()->heap(); }
 };
@@ -90,25 +100,23 @@
   int32_t result;
   SimplifiedLoweringTester<Object*> t;
   FieldAccess load = {kUntaggedBase, 0, Handle<Name>(), Type::Number(),
-                      kMachFloat64};
+                      MachineType::Float64()};
   Node* loaded = t.LoadField(load, t.PointerConstant(&input));
-  NodeProperties::SetBounds(loaded, Bounds(Type::Number()));
+  NodeProperties::SetType(loaded, Type::Number());
   Node* convert = t.NumberToInt32(loaded);
   FieldAccess store = {kUntaggedBase, 0, Handle<Name>(), Type::Signed32(),
-                       kMachInt32};
+                       MachineType::Int32()};
   t.StoreField(store, t.PointerConstant(&result), convert);
   t.Return(t.jsgraph.TrueConstant());
-  t.LowerAllNodes();
+  t.LowerAllNodesAndLowerChanges();
   t.GenerateCode();
 
-  if (Pipeline::SupportedTarget()) {
     FOR_FLOAT64_INPUTS(i) {
       input = *i;
       int32_t expected = DoubleToInt32(*i);
       t.Call();
       CHECK_EQ(expected, result);
     }
-  }
 }
 
 
@@ -119,18 +127,17 @@
   uint32_t result;
   SimplifiedLoweringTester<Object*> t;
   FieldAccess load = {kUntaggedBase, 0, Handle<Name>(), Type::Number(),
-                      kMachFloat64};
+                      MachineType::Float64()};
   Node* loaded = t.LoadField(load, t.PointerConstant(&input));
-  NodeProperties::SetBounds(loaded, Bounds(Type::Number()));
+  NodeProperties::SetType(loaded, Type::Number());
   Node* convert = t.NumberToUint32(loaded);
   FieldAccess store = {kUntaggedBase, 0, Handle<Name>(), Type::Unsigned32(),
-                       kMachUint32};
+                       MachineType::Uint32()};
   t.StoreField(store, t.PointerConstant(&result), convert);
   t.Return(t.jsgraph.TrueConstant());
-  t.LowerAllNodes();
+  t.LowerAllNodesAndLowerChanges();
   t.GenerateCode();
 
-  if (Pipeline::SupportedTarget()) {
     FOR_FLOAT64_INPUTS(i) {
       input = *i;
       uint32_t expected = DoubleToUint32(*i);
@@ -138,7 +145,6 @@
       CHECK_EQ(static_cast<int32_t>(expected), static_cast<int32_t>(result));
     }
   }
-}
 
 
 // Create a simple JSObject with a unique map.
@@ -151,33 +157,31 @@
 
 
 TEST(RunLoadMap) {
-  SimplifiedLoweringTester<Object*> t(kMachAnyTagged);
+  SimplifiedLoweringTester<Object*> t(MachineType::AnyTagged());
   FieldAccess access = AccessBuilder::ForMap();
   Node* load = t.LoadField(access, t.Parameter(0));
   t.Return(load);
 
-  t.LowerAllNodes();
+  t.LowerAllNodesAndLowerChanges();
   t.GenerateCode();
 
-  if (Pipeline::SupportedTarget()) {
-    Handle<JSObject> src = TestObject();
-    Handle<Map> src_map(src->map());
-    Object* result = t.Call(*src);  // TODO(titzer): raw pointers in call
-    CHECK_EQ(*src_map, result);
-  }
+  Handle<JSObject> src = TestObject();
+  Handle<Map> src_map(src->map());
+  Object* result = t.Call(*src);  // TODO(titzer): raw pointers in call
+  CHECK_EQ(*src_map, result);
 }
 
 
 TEST(RunStoreMap) {
-  SimplifiedLoweringTester<int32_t> t(kMachAnyTagged, kMachAnyTagged);
+  SimplifiedLoweringTester<int32_t> t(MachineType::AnyTagged(),
+                                      MachineType::AnyTagged());
   FieldAccess access = AccessBuilder::ForMap();
   t.StoreField(access, t.Parameter(1), t.Parameter(0));
   t.Return(t.jsgraph.TrueConstant());
 
-  t.LowerAllNodes();
+  t.LowerAllNodesAndLowerChanges();
   t.GenerateCode();
 
-  if (Pipeline::SupportedTarget()) {
     Handle<JSObject> src = TestObject();
     Handle<Map> src_map(src->map());
     Handle<JSObject> dst = TestObject();
@@ -185,38 +189,35 @@
     t.Call(*src_map, *dst);  // TODO(titzer): raw pointers in call
     CHECK(*src_map == dst->map());
   }
-}
 
 
 TEST(RunLoadProperties) {
-  SimplifiedLoweringTester<Object*> t(kMachAnyTagged);
+  SimplifiedLoweringTester<Object*> t(MachineType::AnyTagged());
   FieldAccess access = AccessBuilder::ForJSObjectProperties();
   Node* load = t.LoadField(access, t.Parameter(0));
   t.Return(load);
 
-  t.LowerAllNodes();
+  t.LowerAllNodesAndLowerChanges();
   t.GenerateCode();
 
-  if (Pipeline::SupportedTarget()) {
     Handle<JSObject> src = TestObject();
     Handle<FixedArray> src_props(src->properties());
     Object* result = t.Call(*src);  // TODO(titzer): raw pointers in call
     CHECK_EQ(*src_props, result);
-  }
 }
 
 
 TEST(RunLoadStoreMap) {
-  SimplifiedLoweringTester<Object*> t(kMachAnyTagged, kMachAnyTagged);
+  SimplifiedLoweringTester<Object*> t(MachineType::AnyTagged(),
+                                      MachineType::AnyTagged());
   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.LowerAllNodesAndLowerChanges();
   t.GenerateCode();
 
-  if (Pipeline::SupportedTarget()) {
     Handle<JSObject> src = TestObject();
     Handle<Map> src_map(src->map());
     Handle<JSObject> dst = TestObject();
@@ -225,21 +226,19 @@
     CHECK(result->IsMap());
     CHECK_EQ(*src_map, result);
     CHECK(*src_map == dst->map());
-  }
 }
 
 
 TEST(RunLoadStoreFixedArrayIndex) {
-  SimplifiedLoweringTester<Object*> t(kMachAnyTagged);
+  SimplifiedLoweringTester<Object*> t(MachineType::AnyTagged());
   ElementAccess access = AccessBuilder::ForFixedArrayElement();
   Node* load = t.LoadElement(access, t.Parameter(0), t.Int32Constant(0));
   t.StoreElement(access, t.Parameter(0), t.Int32Constant(1), load);
   t.Return(load);
 
-  t.LowerAllNodes();
+  t.LowerAllNodesAndLowerChanges();
   t.GenerateCode();
 
-  if (Pipeline::SupportedTarget()) {
     Handle<FixedArray> array = t.factory()->NewFixedArray(2);
     Handle<JSObject> src = TestObject();
     Handle<JSObject> dst = TestObject();
@@ -249,16 +248,15 @@
     CHECK_EQ(*src, result);
     CHECK_EQ(*src, array->get(0));
     CHECK_EQ(*src, array->get(1));
-  }
 }
 
 
 TEST(RunLoadStoreArrayBuffer) {
-  SimplifiedLoweringTester<Object*> t(kMachAnyTagged);
+  SimplifiedLoweringTester<Object*> t(MachineType::AnyTagged());
   const int index = 12;
   const int array_length = 2 * index;
   ElementAccess buffer_access =
-      AccessBuilder::ForTypedArrayElement(v8::kExternalInt8Array, true);
+      AccessBuilder::ForTypedArrayElement(kExternalInt8Array, true);
   Node* backing_store = t.LoadField(
       AccessBuilder::ForJSArrayBufferBackingStore(), t.Parameter(0));
   Node* load =
@@ -267,12 +265,11 @@
                  load);
   t.Return(t.jsgraph.TrueConstant());
 
-  t.LowerAllNodes();
+  t.LowerAllNodesAndLowerChanges();
   t.GenerateCode();
 
-  if (Pipeline::SupportedTarget()) {
     Handle<JSArrayBuffer> array = t.factory()->NewJSArrayBuffer();
-    Runtime::SetupArrayBufferAllocatingData(t.isolate(), array, array_length);
+    JSArrayBuffer::SetupAllocatingData(array, t.isolate(), array_length);
     uint8_t* data = reinterpret_cast<uint8_t*>(array->backing_store());
     for (int i = 0; i < array_length; i++) {
       data[i] = i;
@@ -287,7 +284,6 @@
       CHECK_EQ(data[i], expected);
     }
   }
-}
 
 
 TEST(RunLoadFieldFromUntaggedBase) {
@@ -296,14 +292,12 @@
   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(), kMachAnyTagged};
+                          Type::Integral32(), MachineType::AnyTagged()};
 
     SimplifiedLoweringTester<Object*> t;
     Node* load = t.LoadField(access, t.PointerConstant(smis));
     t.Return(load);
-    t.LowerAllNodes();
-
-    if (!Pipeline::SupportedTarget()) continue;
+    t.LowerAllNodesAndLowerChanges();
 
     for (int j = -5; j <= 5; j++) {
       Smi* expected = Smi::FromInt(j);
@@ -320,15 +314,13 @@
   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(), kMachAnyTagged};
+                          Type::Integral32(), MachineType::AnyTagged()};
 
-    SimplifiedLoweringTester<Object*> t(kMachAnyTagged);
+    SimplifiedLoweringTester<Object*> t(MachineType::AnyTagged());
     Node* p0 = t.Parameter(0);
     t.StoreField(access, t.PointerConstant(smis), p0);
     t.Return(p0);
-    t.LowerAllNodes();
-
-    if (!Pipeline::SupportedTarget()) continue;
+    t.LowerAllNodesAndLowerChanges();
 
     for (int j = -5; j <= 5; j++) {
       Smi* expected = Smi::FromInt(j);
@@ -348,15 +340,13 @@
     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(),
-                              kMachAnyTagged};
+                              MachineType::AnyTagged()};
 
       SimplifiedLoweringTester<Object*> t;
       Node* load = t.LoadElement(access, t.PointerConstant(smis),
                                  t.Int32Constant(static_cast<int>(j)));
       t.Return(load);
-      t.LowerAllNodes();
-
-      if (!Pipeline::SupportedTarget()) continue;
+      t.LowerAllNodesAndLowerChanges();
 
       for (int k = -5; k <= 5; k++) {
         Smi* expected = Smi::FromInt(k);
@@ -376,16 +366,14 @@
     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(),
-                              kMachAnyTagged};
+                              MachineType::AnyTagged()};
 
-      SimplifiedLoweringTester<Object*> t(kMachAnyTagged);
+      SimplifiedLoweringTester<Object*> t(MachineType::AnyTagged());
       Node* p0 = t.Parameter(0);
       t.StoreElement(access, t.PointerConstant(smis),
                      t.Int32Constant(static_cast<int>(j)), p0);
       t.Return(p0);
-      t.LowerAllNodes();
-
-      if (!Pipeline::SupportedTarget()) continue;
+      t.LowerAllNodesAndLowerChanges();
 
       for (int k = -5; k <= 5; k++) {
         Smi* expected = Smi::FromInt(k);
@@ -450,13 +438,11 @@
     Node* load = t.LoadElement(access, ptr, t.Int32Constant(from_index));
     t.StoreElement(access, ptr, t.Int32Constant(to_index), load);
     t.Return(t.jsgraph.TrueConstant());
-    t.LowerAllNodes();
+    t.LowerAllNodesAndLowerChanges();
     t.GenerateCode();
 
-    if (Pipeline::SupportedTarget()) {
       Object* result = t.Call();
       CHECK_EQ(t.isolate()->heap()->true_value(), result);
-    }
   }
 
   // Create and run code that copies the field in either {untagged_array}
@@ -472,13 +458,11 @@
     Node* load = t.LoadField(from_access, ptr);
     t.StoreField(to_access, ptr, load);
     t.Return(t.jsgraph.TrueConstant());
-    t.LowerAllNodes();
+    t.LowerAllNodesAndLowerChanges();
     t.GenerateCode();
 
-    if (Pipeline::SupportedTarget()) {
       Object* result = t.Call();
       CHECK_EQ(t.isolate()->heap()->true_value(), result);
-    }
   }
 
   // Create and run code that copies the elements from {this} to {that}.
@@ -516,18 +500,15 @@
     t.LowerAllNodes();
     t.GenerateCode();
 
-    if (Pipeline::SupportedTarget()) {
       Object* result = t.Call();
       CHECK_EQ(t.isolate()->heap()->true_value(), result);
-    }
 #endif
   }
 
   E GetElement(int index) {
     BoundsCheck(index);
     if (tagged) {
-      E* raw = reinterpret_cast<E*>(tagged_array->GetDataStartAddress());
-      return raw[index];
+      return GetTaggedElement(index);
     } else {
       return untagged_array[index];
     }
@@ -560,8 +541,19 @@
     CHECK_LT(index, static_cast<int>(num_elements));
     CHECK_EQ(static_cast<int>(ByteSize()), tagged_array->length());
   }
+
+  E GetTaggedElement(int index) {
+    E* raw = reinterpret_cast<E*>(tagged_array->GetDataStartAddress());
+    return raw[index];
+  }
 };
 
+template <>
+double AccessTester<double>::GetTaggedElement(int index) {
+  return ReadDoubleValue(tagged_array->GetDataStartAddress() +
+                         index * sizeof(double));
+}
+
 
 template <typename E>
 static void RunAccessTest(MachineType rep, E* original_elements, size_t num) {
@@ -577,13 +569,11 @@
         } else {
           a.RunCopyElement(i, i + 1);  // Test element read/write.
         }
-        if (Pipeline::SupportedTarget()) {  // verify.
           for (int j = 0; j < num_elements; j++) {
             E expect =
                 j == (i + 1) ? original_elements[i] : original_elements[j];
             CHECK_EQ(expect, a.GetElement(j));
           }
-        }
       }
     }
   }
@@ -593,10 +583,8 @@
       AccessTester<E> a(tf == 1, rep, original_elements, num);
       AccessTester<E> b(tt == 1, rep, original_elements, num);
       a.RunCopyElements(&b);
-      if (Pipeline::SupportedTarget()) {  // verify.
         for (int i = 0; i < num_elements; i++) {
           CHECK_EQ(a.GetElement(i), b.GetElement(i));
-        }
       }
     }
   }
@@ -606,19 +594,19 @@
 TEST(RunAccessTests_uint8) {
   uint8_t data[] = {0x07, 0x16, 0x25, 0x34, 0x43, 0x99,
                     0xab, 0x78, 0x89, 0x19, 0x2b, 0x38};
-  RunAccessTest<uint8_t>(kMachInt8, data, arraysize(data));
+  RunAccessTest<uint8_t>(MachineType::Int8(), data, arraysize(data));
 }
 
 
 TEST(RunAccessTests_uint16) {
   uint16_t data[] = {0x071a, 0x162b, 0x253c, 0x344d, 0x435e, 0x7777};
-  RunAccessTest<uint16_t>(kMachInt16, data, arraysize(data));
+  RunAccessTest<uint16_t>(MachineType::Int16(), data, arraysize(data));
 }
 
 
 TEST(RunAccessTests_int32) {
   int32_t data[] = {-211, 211, 628347, 2000000000, -2000000000, -1, -100000034};
-  RunAccessTest<int32_t>(kMachInt32, data, arraysize(data));
+  RunAccessTest<int32_t>(MachineType::Int32(), data, arraysize(data));
 }
 
 
@@ -632,13 +620,13 @@
                     V8_2PART_INT64(0x30313233, 34353637),
                     V8_2PART_INT64(0xa0a1a2a3, a4a5a6a7),
                     V8_2PART_INT64(0xf0f1f2f3, f4f5f6f7)};
-  RunAccessTest<int64_t>(kMachInt64, data, arraysize(data));
+  RunAccessTest<int64_t>(MachineType::Int64(), data, arraysize(data));
 }
 
 
 TEST(RunAccessTests_float64) {
   double data[] = {1.25, -1.25, 2.75, 11.0, 11100.8};
-  RunAccessTest<double>(kMachFloat64, data, arraysize(data));
+  RunAccessTest<double>(MachineType::Float64(), data, arraysize(data));
 }
 
 
@@ -646,7 +634,30 @@
   Smi* data[] = {Smi::FromInt(-1),    Smi::FromInt(-9),
                  Smi::FromInt(0),     Smi::FromInt(666),
                  Smi::FromInt(77777), Smi::FromInt(Smi::kMaxValue)};
-  RunAccessTest<Smi*>(kMachAnyTagged, data, arraysize(data));
+  RunAccessTest<Smi*>(MachineType::AnyTagged(), data, arraysize(data));
+}
+
+
+TEST(RunAllocate) {
+  PretenureFlag flag[] = {NOT_TENURED, TENURED};
+
+  for (size_t i = 0; i < arraysize(flag); i++) {
+    SimplifiedLoweringTester<HeapObject*> t;
+    FieldAccess access = AccessBuilder::ForMap();
+    Node* size = t.jsgraph.Constant(HeapNumber::kSize);
+    Node* alloc = t.NewNode(t.simplified()->Allocate(flag[i]), size);
+    Node* map = t.jsgraph.Constant(t.factory()->heap_number_map());
+    t.StoreField(access, alloc, map);
+    t.Return(alloc);
+
+    t.LowerAllNodesAndLowerChanges();
+    t.GenerateCode();
+
+      HeapObject* result = t.CallWithPotentialGC<HeapObject>();
+      CHECK(t.heap()->new_space()->Contains(result) || flag[i] == TENURED);
+      CHECK(t.heap()->old_space()->Contains(result) || flag[i] == NOT_TENURED);
+      CHECK(result->IsHeapNumber());
+  }
 }
 
 
@@ -666,22 +677,23 @@
   explicit TestingGraph(Type* p0_type, Type* p1_type = Type::None(),
                         Type* p2_type = Type::None())
       : GraphAndBuilders(main_zone()),
-        typer(graph(), MaybeHandle<Context>()),
+        typer(main_isolate(), graph()),
         javascript(main_zone()),
-        jsgraph(graph(), common(), &javascript, machine()) {
-    start = graph()->NewNode(common()->Start(2));
+        jsgraph(main_isolate(), graph(), common(), &javascript, simplified(),
+                machine()) {
+    start = graph()->NewNode(common()->Start(4));
     graph()->SetStart(start);
     ret =
         graph()->NewNode(common()->Return(), jsgraph.Constant(0), start, start);
-    end = graph()->NewNode(common()->End(), ret);
+    end = graph()->NewNode(common()->End(1), ret);
     graph()->SetEnd(end);
     p0 = graph()->NewNode(common()->Parameter(0), start);
     p1 = graph()->NewNode(common()->Parameter(1), start);
     p2 = graph()->NewNode(common()->Parameter(2), start);
     typer.Run();
-    NodeProperties::SetBounds(p0, Bounds(p0_type));
-    NodeProperties::SetBounds(p1, Bounds(p1_type));
-    NodeProperties::SetBounds(p2, Bounds(p2_type));
+    NodeProperties::SetType(p0, p0_type);
+    NodeProperties::SetType(p1, p1_type);
+    NodeProperties::SetType(p2, p2_type);
   }
 
   void CheckLoweringBinop(IrOpcode::Value expected, const Operator* op) {
@@ -690,6 +702,13 @@
     CHECK_EQ(expected, node->opcode());
   }
 
+  void CheckLoweringStringBinop(IrOpcode::Value expected, const Operator* op) {
+    Node* node = Return(
+        graph()->NewNode(op, p0, p1, graph()->start(), graph()->start()));
+    Lower();
+    CHECK_EQ(expected, node->opcode());
+  }
+
   void CheckLoweringTruncatedBinop(IrOpcode::Value expected, const Operator* op,
                                    const Operator* trunc) {
     Node* node = graph()->NewNode(op, p0, p1);
@@ -698,7 +717,21 @@
     CHECK_EQ(expected, node->opcode());
   }
 
-  void Lower() { SimplifiedLowering(&jsgraph, jsgraph.zone()).LowerAllNodes(); }
+  void Lower() {
+    SourcePositionTable table(jsgraph.graph());
+    SimplifiedLowering(&jsgraph, jsgraph.zone(), &table).LowerAllNodes();
+  }
+
+  void LowerAllNodesAndLowerChanges() {
+    SourcePositionTable table(jsgraph.graph());
+    SimplifiedLowering(&jsgraph, jsgraph.zone(), &table).LowerAllNodes();
+
+    ChangeLowering lowering(&jsgraph);
+    GraphReducer reducer(this->zone(), this->graph());
+    reducer.AddReducer(&lowering);
+    reducer.ReduceGraph();
+    Verifier::Run(this->graph());
+  }
 
   // Inserts the node as the return value of the graph.
   Node* Return(Node* node) {
@@ -710,55 +743,43 @@
   void Effect(Node* node) { ret->ReplaceInput(1, node); }
 
   Node* ExampleWithOutput(MachineType type) {
-    // TODO(titzer): use parameters with guaranteed representations.
-    if (type & kTypeInt32) {
+    if (type.semantic() == MachineSemantic::kInt32) {
       return graph()->NewNode(machine()->Int32Add(), jsgraph.Int32Constant(1),
                               jsgraph.Int32Constant(1));
-    } else if (type & kTypeUint32) {
+    } else if (type.semantic() == MachineSemantic::kUint32) {
       return graph()->NewNode(machine()->Word32Shr(), jsgraph.Int32Constant(1),
                               jsgraph.Int32Constant(1));
-    } else if (type & kRepFloat64) {
+    } else if (type.representation() == MachineRepresentation::kFloat64) {
       return graph()->NewNode(machine()->Float64Add(),
                               jsgraph.Float64Constant(1),
                               jsgraph.Float64Constant(1));
-    } else if (type & kRepBit) {
+    } else if (type.representation() == MachineRepresentation::kBit) {
       return graph()->NewNode(machine()->Word32Equal(),
                               jsgraph.Int32Constant(1),
                               jsgraph.Int32Constant(1));
-    } else if (type & kRepWord64) {
+    } else if (type.representation() == MachineRepresentation::kWord64) {
       return graph()->NewNode(machine()->Int64Add(), Int64Constant(1),
                               Int64Constant(1));
     } else {
-      CHECK(type & kRepTagged);
+      CHECK(type.representation() == MachineRepresentation::kTagged);
       return p0;
     }
   }
 
-  Node* ExampleWithTypeAndRep(Type* type, MachineType mach_type) {
-    FieldAccess access = {kUntaggedBase, 0, Handle<Name>::null(), type,
-                          mach_type};
-    // TODO(titzer): using loads here just to force the representation is ugly.
-    Node* node = graph()->NewNode(simplified()->LoadField(access),
-                                  jsgraph.IntPtrConstant(0), graph()->start(),
-                                  graph()->start());
-    NodeProperties::SetBounds(node, Bounds(type));
-    return node;
-  }
-
   Node* Use(Node* node, MachineType type) {
-    if (type & kTypeInt32) {
+    if (type.semantic() == MachineSemantic::kInt32) {
       return graph()->NewNode(machine()->Int32LessThan(), node,
                               jsgraph.Int32Constant(1));
-    } else if (type & kTypeUint32) {
+    } else if (type.semantic() == MachineSemantic::kUint32) {
       return graph()->NewNode(machine()->Uint32LessThan(), node,
                               jsgraph.Int32Constant(1));
-    } else if (type & kRepFloat64) {
+    } else if (type.representation() == MachineRepresentation::kFloat64) {
       return graph()->NewNode(machine()->Float64Add(), node,
                               jsgraph.Float64Constant(1));
-    } else if (type & kRepWord64) {
+    } else if (type.representation() == MachineRepresentation::kWord64) {
       return graph()->NewNode(machine()->Int64LessThan(), node,
                               Int64Constant(1));
-    } else if (type & kRepWord32) {
+    } else if (type.representation() == MachineRepresentation::kWord32) {
       return graph()->NewNode(machine()->Word32Equal(), node,
                               jsgraph.Int32Constant(1));
     } else {
@@ -787,54 +808,10 @@
 };
 
 
-TEST(LowerAnyToBoolean_bit_bit) {
-  // AnyToBoolean(x: kRepBit) used as kRepBit
-  HandleAndZoneScope scope;
-  Factory* f = scope.main_zone()->isolate()->factory();
-  Handle<Object> zero = f->NewNumber(0);
-  Handle<Object> one = f->NewNumber(1);
-  Type* singleton_zero = Type::Constant(zero, scope.main_zone());
-  Type* singleton_one = Type::Constant(one, scope.main_zone());
-  Type* zero_one_range = Type::Range(zero, one, scope.main_zone());
-  static Type* kTypes[] = {
-      singleton_zero, singleton_one, zero_one_range, Type::Boolean(),
-      Type::Union(Type::Boolean(), singleton_zero, scope.main_zone()),
-      Type::Union(Type::Boolean(), singleton_one, scope.main_zone()),
-      Type::Union(Type::Boolean(), zero_one_range, scope.main_zone())};
-  for (Type* type : kTypes) {
-    TestingGraph t(type);
-    Node* x = t.ExampleWithTypeAndRep(type, kRepBit);
-    Node* cnv = t.graph()->NewNode(t.simplified()->AnyToBoolean(), x);
-    Node* use = t.Branch(cnv);
-    t.Lower();
-    CHECK_EQ(x, use->InputAt(0));
-  }
-}
-
-
-#if V8_TURBOFAN_TARGET
-
-TEST(LowerAnyToBoolean_tagged_tagged) {
-  // AnyToBoolean(x: kRepTagged) used as kRepTagged
-  TestingGraph t(Type::Any());
-  Node* x = t.p0;
-  Node* cnv = t.graph()->NewNode(t.simplified()->AnyToBoolean(), x);
-  Node* use = t.Use(cnv, kRepTagged);
-  t.Return(use);
-  t.Lower();
-  CHECK_EQ(IrOpcode::kCall, cnv->opcode());
-  CHECK_EQ(IrOpcode::kHeapConstant, cnv->InputAt(0)->opcode());
-  CHECK_EQ(x, cnv->InputAt(1));
-  CHECK_EQ(t.jsgraph.NoContextConstant(), cnv->InputAt(2));
-}
-
-#endif
-
-
 TEST(LowerBooleanNot_bit_bit) {
   // BooleanNot(x: kRepBit) used as kRepBit
   TestingGraph t(Type::Boolean());
-  Node* b = t.ExampleWithOutput(kRepBit);
+  Node* b = t.ExampleWithOutput(MachineType::Bool());
   Node* inv = t.graph()->NewNode(t.simplified()->BooleanNot(), b);
   Node* use = t.Branch(inv);
   t.Lower();
@@ -849,9 +826,9 @@
 TEST(LowerBooleanNot_bit_tagged) {
   // BooleanNot(x: kRepBit) used as kRepTagged
   TestingGraph t(Type::Boolean());
-  Node* b = t.ExampleWithOutput(kRepBit);
+  Node* b = t.ExampleWithOutput(MachineType::Bool());
   Node* inv = t.graph()->NewNode(t.simplified()->BooleanNot(), b);
-  Node* use = t.Use(inv, kRepTagged);
+  Node* use = t.Use(inv, MachineType::AnyTagged());
   t.Return(use);
   t.Lower();
   CHECK_EQ(IrOpcode::kChangeBitToBool, use->InputAt(0)->opcode());
@@ -883,7 +860,7 @@
   TestingGraph t(Type::Boolean());
   Node* b = t.p0;
   Node* inv = t.graph()->NewNode(t.simplified()->BooleanNot(), b);
-  Node* use = t.Use(inv, kRepTagged);
+  Node* use = t.Use(inv, MachineType::AnyTagged());
   t.Return(use);
   t.Lower();
   CHECK_EQ(IrOpcode::kChangeBitToBool, use->InputAt(0)->opcode());
@@ -896,11 +873,11 @@
 
 
 TEST(LowerBooleanToNumber_bit_int32) {
-  // BooleanToNumber(x: kRepBit) used as kMachInt32
+  // BooleanToNumber(x: kRepBit) used as MachineType::Int32()
   TestingGraph t(Type::Boolean());
-  Node* b = t.ExampleWithOutput(kRepBit);
+  Node* b = t.ExampleWithOutput(MachineType::Bool());
   Node* cnv = t.graph()->NewNode(t.simplified()->BooleanToNumber(), b);
-  Node* use = t.Use(cnv, kMachInt32);
+  Node* use = t.Use(cnv, MachineType::Int32());
   t.Return(use);
   t.Lower();
   CHECK_EQ(b, use->InputAt(0));
@@ -908,11 +885,11 @@
 
 
 TEST(LowerBooleanToNumber_tagged_int32) {
-  // BooleanToNumber(x: kRepTagged) used as kMachInt32
+  // BooleanToNumber(x: kRepTagged) used as MachineType::Int32()
   TestingGraph t(Type::Boolean());
   Node* b = t.p0;
   Node* cnv = t.graph()->NewNode(t.simplified()->BooleanToNumber(), b);
-  Node* use = t.Use(cnv, kMachInt32);
+  Node* use = t.Use(cnv, MachineType::Int32());
   t.Return(use);
   t.Lower();
   CHECK_EQ(t.machine()->WordEqual()->opcode(), cnv->opcode());
@@ -923,28 +900,28 @@
 
 
 TEST(LowerBooleanToNumber_bit_tagged) {
-  // BooleanToNumber(x: kRepBit) used as kMachAnyTagged
+  // BooleanToNumber(x: kRepBit) used as MachineType::AnyTagged()
   TestingGraph t(Type::Boolean());
-  Node* b = t.ExampleWithOutput(kRepBit);
+  Node* b = t.ExampleWithOutput(MachineType::Bool());
   Node* cnv = t.graph()->NewNode(t.simplified()->BooleanToNumber(), b);
-  Node* use = t.Use(cnv, kMachAnyTagged);
+  Node* use = t.Use(cnv, MachineType::AnyTagged());
   t.Return(use);
   t.Lower();
   CHECK_EQ(b, use->InputAt(0)->InputAt(0));
-  CHECK_EQ(IrOpcode::kChangeInt32ToTagged, use->InputAt(0)->opcode());
+  CHECK_EQ(IrOpcode::kChangeUint32ToTagged, use->InputAt(0)->opcode());
 }
 
 
 TEST(LowerBooleanToNumber_tagged_tagged) {
-  // BooleanToNumber(x: kRepTagged) used as kMachAnyTagged
+  // BooleanToNumber(x: kRepTagged) used as MachineType::AnyTagged()
   TestingGraph t(Type::Boolean());
   Node* b = t.p0;
   Node* cnv = t.graph()->NewNode(t.simplified()->BooleanToNumber(), b);
-  Node* use = t.Use(cnv, kMachAnyTagged);
+  Node* use = t.Use(cnv, MachineType::AnyTagged());
   t.Return(use);
   t.Lower();
   CHECK_EQ(cnv, use->InputAt(0)->InputAt(0));
-  CHECK_EQ(IrOpcode::kChangeInt32ToTagged, use->InputAt(0)->opcode());
+  CHECK_EQ(IrOpcode::kChangeUint32ToTagged, 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();
@@ -996,11 +973,8 @@
 
 TEST(LowerNumberAddSub_to_int32) {
   HandleAndZoneScope scope;
-  Factory* f = scope.main_zone()->isolate()->factory();
-  Type* small_range =
-      Type::Range(f->NewNumber(1), f->NewNumber(10), scope.main_zone());
-  Type* large_range =
-      Type::Range(f->NewNumber(-1e+13), f->NewNumber(1e+14), scope.main_zone());
+  Type* small_range = Type::Range(1, 10, scope.main_zone());
+  Type* large_range = Type::Range(-1e+13, 1e+14, scope.main_zone());
   static Type* types[] = {Type::Signed32(), Type::Integral32(), small_range,
                           large_range};
 
@@ -1020,11 +994,8 @@
 
 TEST(LowerNumberAddSub_to_uint32) {
   HandleAndZoneScope scope;
-  Factory* f = scope.main_zone()->isolate()->factory();
-  Type* small_range =
-      Type::Range(f->NewNumber(1), f->NewNumber(10), scope.main_zone());
-  Type* large_range =
-      Type::Range(f->NewNumber(-1e+13), f->NewNumber(1e+14), scope.main_zone());
+  Type* small_range = Type::Range(1, 10, scope.main_zone());
+  Type* large_range = Type::Range(-1e+13, 1e+14, scope.main_zone());
   static Type* types[] = {Type::Signed32(), Type::Integral32(), small_range,
                           large_range};
 
@@ -1072,33 +1043,11 @@
 }
 
 
-TEST(LowerNumberToInt32_to_nop) {
-  // 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, kRepTagged);
-  t.Return(use);
-  t.Lower();
-  CHECK_EQ(t.p0, use->InputAt(0));
-}
-
-
-TEST(LowerNumberToInt32_to_ChangeTaggedToFloat64) {
-  // 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, kRepFloat64);
-  t.Return(use);
-  t.Lower();
-  CheckChangeOf(IrOpcode::kChangeTaggedToFloat64, t.p0, use->InputAt(0));
-}
-
-
 TEST(LowerNumberToInt32_to_ChangeTaggedToInt32) {
   // 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, kTypeInt32);
+  Node* use = t.Use(trunc, MachineType::Int32());
   t.Return(use);
   t.Lower();
   CheckChangeOf(IrOpcode::kChangeTaggedToInt32, t.p0, use->InputAt(0));
@@ -1106,11 +1055,11 @@
 
 
 TEST(LowerNumberToInt32_to_TruncateFloat64ToInt32) {
-  // NumberToInt32(x: kRepFloat64) used as kMachInt32
+  // NumberToInt32(x: kRepFloat64) used as MachineType::Int32()
   TestingGraph t(Type::Number());
-  Node* p0 = t.ExampleWithTypeAndRep(Type::Number(), kMachFloat64);
+  Node* p0 = t.ExampleWithOutput(MachineType::Float64());
   Node* trunc = t.graph()->NewNode(t.simplified()->NumberToInt32(), p0);
-  Node* use = t.Use(trunc, kMachInt32);
+  Node* use = t.Use(trunc, MachineType::Int32());
   t.Return(use);
   t.Lower();
   CheckChangeOf(IrOpcode::kTruncateFloat64ToInt32, p0, use->InputAt(0));
@@ -1118,10 +1067,10 @@
 
 
 TEST(LowerNumberToInt32_to_TruncateFloat64ToInt32_with_change) {
-  // NumberToInt32(x: kTypeNumber | kRepTagged) used as kMachInt32
+  // NumberToInt32(x: kTypeNumber | kRepTagged) used as MachineType::Int32()
   TestingGraph t(Type::Number());
   Node* trunc = t.graph()->NewNode(t.simplified()->NumberToInt32(), t.p0);
-  Node* use = t.Use(trunc, kMachInt32);
+  Node* use = t.Use(trunc, MachineType::Int32());
   t.Return(use);
   t.Lower();
   Node* node = use->InputAt(0);
@@ -1132,33 +1081,11 @@
 }
 
 
-TEST(LowerNumberToUint32_to_nop) {
-  // 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, kRepTagged);
-  t.Return(use);
-  t.Lower();
-  CHECK_EQ(t.p0, use->InputAt(0));
-}
-
-
-TEST(LowerNumberToUint32_to_ChangeTaggedToFloat64) {
-  // 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, kRepFloat64);
-  t.Return(use);
-  t.Lower();
-  CheckChangeOf(IrOpcode::kChangeTaggedToFloat64, t.p0, use->InputAt(0));
-}
-
-
 TEST(LowerNumberToUint32_to_ChangeTaggedToUint32) {
   // 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, kTypeUint32);
+  Node* use = t.Use(trunc, MachineType::Uint32());
   t.Return(use);
   t.Lower();
   CheckChangeOf(IrOpcode::kChangeTaggedToUint32, t.p0, use->InputAt(0));
@@ -1166,13 +1093,13 @@
 
 
 TEST(LowerNumberToUint32_to_TruncateFloat64ToInt32) {
-  // NumberToUint32(x: kRepFloat64) used as kMachUint32
+  // NumberToUint32(x: kRepFloat64) used as MachineType::Uint32()
   TestingGraph t(Type::Number());
-  Node* p0 = t.ExampleWithOutput(kMachFloat64);
+  Node* p0 = t.ExampleWithOutput(MachineType::Float64());
   // TODO(titzer): run the typer here, or attach machine type to param.
-  NodeProperties::SetBounds(p0, Bounds(Type::Number()));
+  NodeProperties::SetType(p0, Type::Number());
   Node* trunc = t.graph()->NewNode(t.simplified()->NumberToUint32(), p0);
-  Node* use = t.Use(trunc, kMachUint32);
+  Node* use = t.Use(trunc, MachineType::Uint32());
   t.Return(use);
   t.Lower();
   CheckChangeOf(IrOpcode::kTruncateFloat64ToInt32, p0, use->InputAt(0));
@@ -1180,10 +1107,10 @@
 
 
 TEST(LowerNumberToUint32_to_TruncateFloat64ToInt32_with_change) {
-  // NumberToInt32(x: kTypeNumber | kRepTagged) used as kMachUint32
+  // NumberToInt32(x: kTypeNumber | kRepTagged) used as MachineType::Uint32()
   TestingGraph t(Type::Number());
   Node* trunc = t.graph()->NewNode(t.simplified()->NumberToUint32(), t.p0);
-  Node* use = t.Use(trunc, kMachUint32);
+  Node* use = t.Use(trunc, MachineType::Uint32());
   t.Return(use);
   t.Lower();
   Node* node = use->InputAt(0);
@@ -1197,67 +1124,15 @@
 TEST(LowerNumberToUint32_to_TruncateFloat64ToInt32_uint32) {
   // NumberToUint32(x: kRepFloat64) used as kRepWord32
   TestingGraph t(Type::Unsigned32());
-  Node* input = t.ExampleWithTypeAndRep(Type::Number(), kMachFloat64);
+  Node* input = t.ExampleWithOutput(MachineType::Float64());
   Node* trunc = t.graph()->NewNode(t.simplified()->NumberToUint32(), input);
-  Node* use = t.Use(trunc, kRepWord32);
+  Node* use = t.Use(trunc, MachineType::RepWord32());
   t.Return(use);
   t.Lower();
   CheckChangeOf(IrOpcode::kTruncateFloat64ToInt32, input, use->InputAt(0));
 }
 
 
-TEST(LowerNumberToUI32_of_Float64_used_as_word32) {
-  // NumberTo(Int,Uint)32(x: kRepFloat64 | kType(Int,Uint)32) used as
-  // kType(Int,Uint)32 | kRepWord32
-  Type* types[] = {Type::Signed32(), Type::Unsigned32()};
-  MachineType mach[] = {kTypeInt32, kTypeUint32, kMachNone};
-
-  for (int i = 0; i < 2; i++) {
-    for (int u = 0; u < 3; u++) {
-      TestingGraph t(types[i]);
-      Node* input = t.ExampleWithTypeAndRep(
-          types[i], static_cast<MachineType>(kRepFloat64 | mach[i]));
-      const Operator* op = i == 0 ? t.simplified()->NumberToInt32()
-                                  : t.simplified()->NumberToUint32();
-      Node* trunc = t.graph()->NewNode(op, input);
-      Node* use = t.Use(trunc, static_cast<MachineType>(kRepWord32 | mach[u]));
-      t.Return(use);
-      t.Lower();
-      IrOpcode::Value opcode = i == 0 ? IrOpcode::kChangeFloat64ToInt32
-                                      : IrOpcode::kChangeFloat64ToUint32;
-      CheckChangeOf(opcode, input, use->InputAt(0));
-    }
-  }
-}
-
-
-TEST(LowerNumberToUI32_of_Float64_used_as_tagged) {
-  // NumberTo(Int,Uint)32(x: kRepFloat64 | kType(Int,Uint)32) used as
-  // kType(Int,Uint)32 | kRepTagged
-  Type* types[] = {Type::Signed32(), Type::Unsigned32(), Type::Any()};
-  MachineType mach[] = {kTypeInt32, kTypeUint32, kMachNone};
-
-  for (int i = 0; i < 2; i++) {
-    for (int u = 0; u < 3; u++) {
-      TestingGraph t(types[i]);
-      Node* input = t.ExampleWithTypeAndRep(
-          types[i], static_cast<MachineType>(kRepFloat64 | mach[i]));
-      const Operator* op = i == 0 ? t.simplified()->NumberToInt32()
-                                  : t.simplified()->NumberToUint32();
-      Node* trunc = t.graph()->NewNode(op, input);
-      // TODO(titzer): we use the store here to force the representation.
-      FieldAccess access = {kTaggedBase, 0, Handle<Name>(), types[u],
-                            static_cast<MachineType>(mach[u] | kRepTagged)};
-      Node* store = t.graph()->NewNode(t.simplified()->StoreField(access), t.p0,
-                                       trunc, t.start, t.start);
-      t.Effect(store);
-      t.Lower();
-      CheckChangeOf(IrOpcode::kChangeFloat64ToTagged, input, store->InputAt(2));
-    }
-  }
-}
-
-
 TEST(LowerReferenceEqual_to_wordeq) {
   TestingGraph t(Type::Any(), Type::Any());
   IrOpcode::Value opcode =
@@ -1267,7 +1142,6 @@
 
 
 TEST(LowerStringOps_to_call_and_compare) {
-  if (Pipeline::SupportedTarget()) {
     // These tests need linkage for the calls.
     TestingGraph t(Type::String(), Type::String());
     IrOpcode::Value compare_eq =
@@ -1276,18 +1150,18 @@
         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());
+    t.CheckLoweringStringBinop(compare_eq, t.simplified()->StringEqual());
+    t.CheckLoweringStringBinop(compare_lt, t.simplified()->StringLessThan());
+    t.CheckLoweringStringBinop(compare_le,
+                               t.simplified()->StringLessThanOrEqual());
   }
-}
 
 
-void CheckChangeInsertion(IrOpcode::Value expected, MachineType from,
-                          MachineType to) {
+  void CheckChangeInsertion(IrOpcode::Value expected, MachineType from,
+                            MachineType to, Type* type = Type::Any()) {
   TestingGraph t(Type::Any());
   Node* in = t.ExampleWithOutput(from);
+  NodeProperties::SetType(in, type);
   Node* use = t.Use(in, to);
   t.Return(use);
   t.Lower();
@@ -1297,34 +1171,43 @@
 
 
 TEST(InsertBasicChanges) {
-  CheckChangeInsertion(IrOpcode::kChangeFloat64ToInt32, kRepFloat64,
-                       kTypeInt32);
-  CheckChangeInsertion(IrOpcode::kChangeFloat64ToUint32, kRepFloat64,
-                       kTypeUint32);
-  CheckChangeInsertion(IrOpcode::kChangeTaggedToInt32, kRepTagged, kTypeInt32);
-  CheckChangeInsertion(IrOpcode::kChangeTaggedToUint32, kRepTagged,
-                       kTypeUint32);
+  CheckChangeInsertion(IrOpcode::kChangeFloat64ToInt32, MachineType::Float64(),
+                       MachineType::Int32(), Type::Signed32());
+  CheckChangeInsertion(IrOpcode::kChangeFloat64ToUint32, MachineType::Float64(),
+                       MachineType::Uint32(), Type::Unsigned32());
+  CheckChangeInsertion(IrOpcode::kTruncateFloat64ToInt32,
+                       MachineType::Float64(), MachineType::Uint32(),
+                       Type::Integral32());
+  CheckChangeInsertion(IrOpcode::kChangeTaggedToInt32, MachineType::AnyTagged(),
+                       MachineType::Int32(), Type::Signed32());
+  CheckChangeInsertion(IrOpcode::kChangeTaggedToUint32,
+                       MachineType::AnyTagged(), MachineType::Uint32(),
+                       Type::Unsigned32());
 
-  CheckChangeInsertion(IrOpcode::kChangeFloat64ToTagged, kRepFloat64,
-                       kRepTagged);
-  CheckChangeInsertion(IrOpcode::kChangeTaggedToFloat64, kRepTagged,
-                       kRepFloat64);
+  CheckChangeInsertion(IrOpcode::kChangeFloat64ToTagged, MachineType::Float64(),
+                       MachineType::AnyTagged());
+  CheckChangeInsertion(IrOpcode::kChangeTaggedToFloat64,
+                       MachineType::AnyTagged(), MachineType::Float64());
 
-  CheckChangeInsertion(IrOpcode::kChangeInt32ToFloat64, kTypeInt32,
-                       kRepFloat64);
-  CheckChangeInsertion(IrOpcode::kChangeInt32ToTagged, kTypeInt32, kRepTagged);
+  CheckChangeInsertion(IrOpcode::kChangeInt32ToFloat64, MachineType::Int32(),
+                       MachineType::Float64());
+  CheckChangeInsertion(IrOpcode::kChangeInt32ToTagged, MachineType::Int32(),
+                       MachineType::AnyTagged());
 
-  CheckChangeInsertion(IrOpcode::kChangeUint32ToFloat64, kTypeUint32,
-                       kRepFloat64);
-  CheckChangeInsertion(IrOpcode::kChangeUint32ToTagged, kTypeUint32,
-                       kRepTagged);
+  CheckChangeInsertion(IrOpcode::kChangeUint32ToFloat64, MachineType::Uint32(),
+                       MachineType::Float64());
+  CheckChangeInsertion(IrOpcode::kChangeUint32ToTagged, MachineType::Uint32(),
+                       MachineType::AnyTagged());
 }
 
 
 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);
+  Node* binop =
+      op->ControlInputCount() == 0
+          ? t->graph()->NewNode(op, t->p0, t->p1)
+          : t->graph()->NewNode(op, t->p0, t->p1, t->graph()->start());
   t->Return(binop);
   t->Lower();
   CHECK_EQ(input_change, binop->InputAt(0)->opcode());
@@ -1427,7 +1310,8 @@
   CHECK_EQ(IrOpcode::kInt32Add, mindex.node()->opcode());
   CHECK(mindex.right().Is(access.header_size - access.tag()));
 
-  const int element_size_shift = ElementSizeLog2Of(access.machine_type);
+  const int element_size_shift =
+      ElementSizeLog2Of(access.machine_type.representation());
   if (element_size_shift) {
     Int32BinopMatcher shl(mindex.left().node());
     CHECK_EQ(IrOpcode::kWord32Shl, shl.node()->opcode());
@@ -1439,9 +1323,10 @@
 }
 
 
-const MachineType kMachineReps[] = {kRepBit,       kMachInt8,  kMachInt16,
-                                    kMachInt32,    kMachInt64, kMachFloat64,
-                                    kMachAnyTagged};
+const MachineType kMachineReps[] = {
+    MachineType::Int8(),     MachineType::Int16(), MachineType::Int32(),
+    MachineType::Uint32(),   MachineType::Int64(), MachineType::Float64(),
+    MachineType::AnyTagged()};
 
 }  // namespace
 
@@ -1453,43 +1338,62 @@
     FieldAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize,
                           Handle<Name>::null(), Type::Any(), kMachineReps[i]};
 
-    Node* load =
-        t.graph()->NewNode(t.simplified()->LoadField(access), t.p0, t.start);
+    Node* load = t.graph()->NewNode(t.simplified()->LoadField(access), t.p0,
+                                    t.start, t.start);
     Node* use = t.Use(load, kMachineReps[i]);
     t.Return(use);
-    t.Lower();
+    t.LowerAllNodesAndLowerChanges();
     CHECK_EQ(IrOpcode::kLoad, load->opcode());
     CHECK_EQ(t.p0, load->InputAt(0));
     CheckFieldAccessArithmetic(access, load);
 
-    MachineType rep = OpParameter<MachineType>(load);
+    MachineType rep = LoadRepresentationOf(load->op());
     CHECK_EQ(kMachineReps[i], rep);
   }
 }
 
 
 TEST(LowerStoreField_to_store) {
-  TestingGraph t(Type::Any(), Type::Signed32());
+  {
+    TestingGraph t(Type::Any(), Type::Signed32());
 
-  for (size_t i = 0; i < arraysize(kMachineReps); i++) {
-    FieldAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize,
-                          Handle<Name>::null(), Type::Any(), kMachineReps[i]};
+    for (size_t i = 0; i < arraysize(kMachineReps); i++) {
+      FieldAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize,
+                            Handle<Name>::null(), Type::Any(), kMachineReps[i]};
 
 
-    Node* val = t.ExampleWithOutput(kMachineReps[i]);
-    Node* store = t.graph()->NewNode(t.simplified()->StoreField(access), t.p0,
-                                     val, t.start, t.start);
-    t.Effect(store);
-    t.Lower();
-    CHECK_EQ(IrOpcode::kStore, store->opcode());
-    CHECK_EQ(val, store->InputAt(2));
-    CheckFieldAccessArithmetic(access, store);
+      Node* val = t.ExampleWithOutput(kMachineReps[i]);
+      Node* store = t.graph()->NewNode(t.simplified()->StoreField(access), t.p0,
+                                       val, t.start, t.start);
+      t.Effect(store);
+      t.LowerAllNodesAndLowerChanges();
+      CHECK_EQ(IrOpcode::kStore, store->opcode());
+      CHECK_EQ(val, store->InputAt(2));
+      CheckFieldAccessArithmetic(access, store);
 
-    StoreRepresentation rep = OpParameter<StoreRepresentation>(store);
-    if (kMachineReps[i] & kRepTagged) {
-      CHECK_EQ(kFullWriteBarrier, rep.write_barrier_kind());
+      StoreRepresentation rep = StoreRepresentationOf(store->op());
+      if (kMachineReps[i].representation() == MachineRepresentation::kTagged) {
+        CHECK_EQ(kFullWriteBarrier, rep.write_barrier_kind());
+      }
+      CHECK_EQ(kMachineReps[i].representation(), rep.representation());
     }
-    CHECK_EQ(kMachineReps[i], rep.machine_type());
+  }
+  {
+    HandleAndZoneScope scope;
+    Zone* z = scope.main_zone();
+    TestingGraph t(Type::Any(), Type::Intersect(Type::SignedSmall(),
+                                                Type::TaggedSigned(), z));
+    FieldAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize,
+                          Handle<Name>::null(), Type::Any(),
+                          MachineType::AnyTagged()};
+    Node* store = t.graph()->NewNode(t.simplified()->StoreField(access), t.p0,
+                                     t.p1, t.start, t.start);
+    t.Effect(store);
+    t.LowerAllNodesAndLowerChanges();
+    CHECK_EQ(IrOpcode::kStore, store->opcode());
+    CHECK_EQ(t.p1, store->InputAt(2));
+    StoreRepresentation rep = StoreRepresentationOf(store->op());
+    CHECK_EQ(kNoWriteBarrier, rep.write_barrier_kind());
   }
 }
 
@@ -1505,38 +1409,57 @@
                                     t.p1, t.start, t.start);
     Node* use = t.Use(load, kMachineReps[i]);
     t.Return(use);
-    t.Lower();
+    t.LowerAllNodesAndLowerChanges();
     CHECK_EQ(IrOpcode::kLoad, load->opcode());
     CHECK_EQ(t.p0, load->InputAt(0));
     CheckElementAccessArithmetic(access, load);
 
-    MachineType rep = OpParameter<MachineType>(load);
+    MachineType rep = LoadRepresentationOf(load->op());
     CHECK_EQ(kMachineReps[i], rep);
   }
 }
 
 
 TEST(LowerStoreElement_to_store) {
-  TestingGraph t(Type::Any(), Type::Signed32());
+  {
+    TestingGraph t(Type::Any(), Type::Signed32());
 
-  for (size_t i = 0; i < arraysize(kMachineReps); i++) {
-    ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize,
-                            Type::Any(), kMachineReps[i]};
+    for (size_t i = 0; i < arraysize(kMachineReps); i++) {
+      ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize,
+                              Type::Any(), kMachineReps[i]};
 
-    Node* val = t.ExampleWithOutput(kMachineReps[i]);
-    Node* store = t.graph()->NewNode(t.simplified()->StoreElement(access), t.p0,
-                                     t.p1, val, t.start, t.start);
-    t.Effect(store);
-    t.Lower();
-    CHECK_EQ(IrOpcode::kStore, store->opcode());
-    CHECK_EQ(val, store->InputAt(2));
-    CheckElementAccessArithmetic(access, store);
+      Node* val = t.ExampleWithOutput(kMachineReps[i]);
+      Node* store = t.graph()->NewNode(t.simplified()->StoreElement(access),
+                                       t.p0, t.p1, val, t.start, t.start);
+      t.Effect(store);
+      t.LowerAllNodesAndLowerChanges();
+      CHECK_EQ(IrOpcode::kStore, store->opcode());
+      CHECK_EQ(val, store->InputAt(2));
+      CheckElementAccessArithmetic(access, store);
 
-    StoreRepresentation rep = OpParameter<StoreRepresentation>(store);
-    if (kMachineReps[i] & kRepTagged) {
-      CHECK_EQ(kFullWriteBarrier, rep.write_barrier_kind());
+      StoreRepresentation rep = StoreRepresentationOf(store->op());
+      if (kMachineReps[i].representation() == MachineRepresentation::kTagged) {
+        CHECK_EQ(kFullWriteBarrier, rep.write_barrier_kind());
+      }
+      CHECK_EQ(kMachineReps[i].representation(), rep.representation());
     }
-    CHECK_EQ(kMachineReps[i], rep.machine_type());
+  }
+  {
+    HandleAndZoneScope scope;
+    Zone* z = scope.main_zone();
+    TestingGraph t(
+        Type::Any(), Type::Signed32(),
+        Type::Intersect(Type::SignedSmall(), Type::TaggedSigned(), z));
+    ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize,
+                            Type::Any(), MachineType::AnyTagged()};
+    Node* store = t.graph()->NewNode(t.simplified()->StoreElement(access), t.p0,
+                                     t.p1, t.p2, t.start, t.start);
+    t.Effect(store);
+    t.LowerAllNodesAndLowerChanges();
+    CHECK_EQ(IrOpcode::kStore, store->opcode());
+    CHECK_EQ(t.p2, store->InputAt(2));
+    StoreRepresentation rep = StoreRepresentationOf(store->op());
+    CHECK_EQ(kNoWriteBarrier, rep.write_barrier_kind());
   }
 }
 
@@ -1546,17 +1469,15 @@
   //   Load(obj, Int32Add(Int32Mul(ChangeTaggedToInt32(index), #k), #k))
   TestingGraph t(Type::Any(), Type::Signed32());
   ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, Type::Any(),
-                          kMachAnyTagged};
+                          MachineType::AnyTagged()};
 
   Node* load = t.graph()->NewNode(t.simplified()->LoadElement(access), t.p0,
                                   t.p1, t.start, t.start);
   t.Return(load);
   t.Lower();
-  CHECK_EQ(IrOpcode::kLoad, load->opcode());
+  CHECK_EQ(IrOpcode::kLoadElement, load->opcode());
   CHECK_EQ(t.p0, load->InputAt(0));
-
-  Node* index = CheckElementAccessArithmetic(access, load);
-  CheckChangeOf(IrOpcode::kChangeTaggedToInt32, t.p1, index);
+  CheckChangeOf(IrOpcode::kChangeTaggedToInt32, t.p1, load->InputAt(1));
 }
 
 
@@ -1565,18 +1486,16 @@
   //   Store(obj, Int32Add(Int32Mul(ChangeTaggedToInt32(index), #k), #k), val)
   TestingGraph t(Type::Any(), Type::Signed32());
   ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, Type::Any(),
-                          kMachAnyTagged};
+                          MachineType::AnyTagged()};
 
   Node* store =
       t.graph()->NewNode(t.simplified()->StoreElement(access), t.p0, t.p1,
                          t.jsgraph.TrueConstant(), t.start, t.start);
   t.Effect(store);
   t.Lower();
-  CHECK_EQ(IrOpcode::kStore, store->opcode());
+  CHECK_EQ(IrOpcode::kStoreElement, store->opcode());
   CHECK_EQ(t.p0, store->InputAt(0));
-
-  Node* index = CheckElementAccessArithmetic(access, store);
-  CheckChangeOf(IrOpcode::kChangeTaggedToInt32, t.p1, index);
+  CheckChangeOf(IrOpcode::kChangeTaggedToInt32, t.p1, store->InputAt(1));
 }
 
 
@@ -1584,13 +1503,13 @@
   // TODO(titzer): test all load/store representation change insertions.
   TestingGraph t(Type::Any(), Type::Signed32(), Type::Any());
   ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, Type::Any(),
-                          kMachFloat64};
+                          MachineType::Float64()};
 
   Node* load = t.graph()->NewNode(t.simplified()->LoadElement(access), t.p0,
                                   t.p1, t.start, t.start);
   t.Return(load);
   t.Lower();
-  CHECK_EQ(IrOpcode::kLoad, load->opcode());
+  CHECK_EQ(IrOpcode::kLoadElement, load->opcode());
   CHECK_EQ(t.p0, load->InputAt(0));
   CheckChangeOf(IrOpcode::kChangeFloat64ToTagged, load, t.ret->InputAt(0));
 }
@@ -1600,13 +1519,14 @@
   // 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(), kMachFloat64};
+                        Handle<Name>::null(), Type::Any(),
+                        MachineType::Float64()};
 
-  Node* load =
-      t.graph()->NewNode(t.simplified()->LoadField(access), t.p0, t.start);
+  Node* load = t.graph()->NewNode(t.simplified()->LoadField(access), t.p0,
+                                  t.start, t.start);
   t.Return(load);
   t.Lower();
-  CHECK_EQ(IrOpcode::kLoad, load->opcode());
+  CHECK_EQ(IrOpcode::kLoadField, load->opcode());
   CHECK_EQ(t.p0, load->InputAt(0));
   CheckChangeOf(IrOpcode::kChangeFloat64ToTagged, load, t.ret->InputAt(0));
 }
@@ -1616,7 +1536,7 @@
   // TODO(titzer): test all load/store representation change insertions.
   TestingGraph t(Type::Any(), Type::Signed32());
   ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, Type::Any(),
-                          kMachFloat64};
+                          MachineType::Float64()};
 
   Node* store =
       t.graph()->NewNode(t.simplified()->StoreElement(access), t.p0,
@@ -1624,7 +1544,7 @@
   t.Effect(store);
   t.Lower();
 
-  CHECK_EQ(IrOpcode::kStore, store->opcode());
+  CHECK_EQ(IrOpcode::kStoreElement, store->opcode());
   CHECK_EQ(t.p0, store->InputAt(0));
   CheckChangeOf(IrOpcode::kChangeTaggedToFloat64, t.p1, store->InputAt(2));
 }
@@ -1634,76 +1554,59 @@
   // 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(), kMachFloat64};
+                        Handle<Name>::null(), Type::Any(),
+                        MachineType::Float64()};
 
   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(IrOpcode::kStoreField, store->opcode());
   CHECK_EQ(t.p0, store->InputAt(0));
-  CheckChangeOf(IrOpcode::kChangeTaggedToFloat64, t.p1, store->InputAt(2));
+  CheckChangeOf(IrOpcode::kChangeTaggedToFloat64, t.p1, store->InputAt(1));
 }
 
 
 TEST(UpdatePhi) {
   TestingGraph t(Type::Any(), Type::Signed32());
-  static const MachineType kMachineTypes[] = {kMachInt32, kMachUint32,
-                                              kMachFloat64};
+  static const MachineType kMachineTypes[] = {
+      MachineType::Int32(), MachineType::Uint32(), MachineType::Float64()};
   Type* kTypes[] = {Type::Signed32(), Type::Unsigned32(), Type::Number()};
 
   for (size_t i = 0; i < arraysize(kMachineTypes); i++) {
     FieldAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize,
                           Handle<Name>::null(), kTypes[i], 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);
+    Node* load0 = t.graph()->NewNode(t.simplified()->LoadField(access), t.p0,
+                                     t.start, t.start);
+    Node* load1 = t.graph()->NewNode(t.simplified()->LoadField(access), t.p1,
+                                     t.start, t.start);
+    Node* phi =
+        t.graph()->NewNode(t.common()->Phi(MachineRepresentation::kTagged, 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)));
+    CHECK_EQ(kMachineTypes[i].representation(), PhiRepresentationOf(phi->op()));
   }
 }
 
 
 TEST(RunNumberDivide_minus_1_TruncatingToInt32) {
-  SimplifiedLoweringTester<Object*> t(kMachAnyTagged);
+  SimplifiedLoweringTester<Object*> t(MachineType::AnyTagged());
   Node* num = t.NumberToInt32(t.Parameter(0));
   Node* div = t.NumberDivide(num, t.jsgraph.Constant(-1));
   Node* trunc = t.NumberToInt32(div);
   t.Return(trunc);
 
-  if (Pipeline::SupportedTarget()) {
-    t.LowerAllNodesAndLowerChanges();
-    t.GenerateCode();
+  t.LowerAllNodesAndLowerChanges();
+  t.GenerateCode();
 
-    FOR_INT32_INPUTS(i) {
-      int32_t x = 0 - *i;
-      t.CheckNumberCall(static_cast<double>(x), static_cast<double>(*i));
-    }
-  }
-}
-
-
-TEST(NumberMultiply_TruncatingToInt32) {
-  int32_t constants[] = {-100, -10, -1, 0, 1, 100, 1000};
-
-  for (size_t i = 0; i < arraysize(constants); i++) {
-    TestingGraph t(Type::Signed32());
-    Node* k = t.jsgraph.Constant(constants[i]);
-    Node* mul = t.graph()->NewNode(t.simplified()->NumberMultiply(), t.p0, k);
-    Node* trunc = t.graph()->NewNode(t.simplified()->NumberToInt32(), mul);
-    t.Return(trunc);
-    t.Lower();
-
-    CHECK_EQ(IrOpcode::kInt32Mul, mul->opcode());
+  FOR_INT32_INPUTS(i) {
+    int32_t x = 0 - *i;
+    t.CheckNumberCall(static_cast<double>(x), static_cast<double>(*i));
   }
 }
 
@@ -1713,13 +1616,12 @@
 
   for (size_t i = 0; i < arraysize(constants); i++) {
     double k = static_cast<double>(constants[i]);
-    SimplifiedLoweringTester<Object*> t(kMachAnyTagged);
+    SimplifiedLoweringTester<Object*> t(MachineType::AnyTagged());
     Node* num = t.NumberToInt32(t.Parameter(0));
     Node* mul = t.NumberMultiply(num, t.jsgraph.Constant(k));
     Node* trunc = t.NumberToInt32(mul);
     t.Return(trunc);
 
-    if (Pipeline::SupportedTarget()) {
       t.LowerAllNodesAndLowerChanges();
       t.GenerateCode();
 
@@ -1728,7 +1630,6 @@
         t.CheckNumberCall(static_cast<double>(x), static_cast<double>(*i));
       }
     }
-  }
 }
 
 
@@ -1737,33 +1638,30 @@
 
   for (size_t i = 0; i < arraysize(constants); i++) {
     double k = static_cast<double>(constants[i]);
-    SimplifiedLoweringTester<Object*> t(kMachAnyTagged);
+    SimplifiedLoweringTester<Object*> t(MachineType::AnyTagged());
     Node* num = t.NumberToUint32(t.Parameter(0));
     Node* mul = t.NumberMultiply(num, t.jsgraph.Constant(k));
     Node* trunc = t.NumberToUint32(mul);
     t.Return(trunc);
 
-    if (Pipeline::SupportedTarget()) {
       t.LowerAllNodesAndLowerChanges();
       t.GenerateCode();
 
       FOR_UINT32_INPUTS(i) {
         uint32_t x = DoubleToUint32(static_cast<double>(*i) * k);
         t.CheckNumberCall(static_cast<double>(x), static_cast<double>(*i));
-      }
     }
   }
 }
 
 
 TEST(RunNumberDivide_2_TruncatingToUint32) {
-  SimplifiedLoweringTester<Object*> t(kMachAnyTagged);
+  SimplifiedLoweringTester<Object*> t(MachineType::AnyTagged());
   Node* num = t.NumberToUint32(t.Parameter(0));
   Node* div = t.NumberDivide(num, t.jsgraph.Constant(2));
   Node* trunc = t.NumberToUint32(div);
   t.Return(trunc);
 
-  if (Pipeline::SupportedTarget()) {
     t.LowerAllNodesAndLowerChanges();
     t.GenerateCode();
 
@@ -1771,7 +1669,6 @@
       uint32_t x = DoubleToUint32(static_cast<double>(*i / 2.0));
       t.CheckNumberCall(static_cast<double>(x), static_cast<double>(*i));
     }
-  }
 }
 
 
@@ -1805,7 +1702,7 @@
     TestingGraph t(Type::Signed32());
     Node* k = t.jsgraph.Constant(constants[i]);
     Node* div = t.graph()->NewNode(t.simplified()->NumberDivide(), t.p0, k);
-    Node* use = t.Use(div, kMachInt32);
+    Node* use = t.Use(div, MachineType::Int32());
     t.Return(use);
     t.Lower();
 
@@ -1819,13 +1716,12 @@
 
   for (size_t i = 0; i < arraysize(constants); i++) {
     int32_t k = constants[i];
-    SimplifiedLoweringTester<Object*> t(kMachAnyTagged);
+    SimplifiedLoweringTester<Object*> t(MachineType::AnyTagged());
     Node* num = t.NumberToInt32(t.Parameter(0));
     Node* div = t.NumberDivide(num, t.jsgraph.Constant(k));
     Node* trunc = t.NumberToInt32(div);
     t.Return(trunc);
 
-    if (Pipeline::SupportedTarget()) {
       t.LowerAllNodesAndLowerChanges();
       t.GenerateCode();
 
@@ -1833,7 +1729,6 @@
         if (*i == INT_MAX) continue;  // exclude max int.
         int32_t x = DoubleToInt32(static_cast<double>(*i) / k);
         t.CheckNumberCall(static_cast<double>(x), static_cast<double>(*i));
-      }
     }
   }
 }
@@ -1846,7 +1741,7 @@
     TestingGraph t(Type::Unsigned32());
     Node* k = t.jsgraph.Constant(constants[i]);
     Node* div = t.graph()->NewNode(t.simplified()->NumberDivide(), t.p0, k);
-    Node* use = t.Use(div, kMachUint32);
+    Node* use = t.Use(div, MachineType::Uint32());
     t.Return(use);
     t.Lower();
 
@@ -1860,20 +1755,18 @@
 
   for (size_t i = 0; i < arraysize(constants); i++) {
     uint32_t k = constants[i];
-    SimplifiedLoweringTester<Object*> t(kMachAnyTagged);
+    SimplifiedLoweringTester<Object*> t(MachineType::AnyTagged());
     Node* num = t.NumberToUint32(t.Parameter(0));
     Node* div = t.NumberDivide(num, t.jsgraph.Constant(static_cast<double>(k)));
     Node* trunc = t.NumberToUint32(div);
     t.Return(trunc);
 
-    if (Pipeline::SupportedTarget()) {
       t.LowerAllNodesAndLowerChanges();
       t.GenerateCode();
 
       FOR_UINT32_INPUTS(i) {
         uint32_t x = *i / k;
         t.CheckNumberCall(static_cast<double>(x), static_cast<double>(*i));
-      }
     }
   }
 }
@@ -1884,7 +1777,7 @@
     TestingGraph t(Type::Signed32());
     Node* k = t.jsgraph.Constant(-1);
     Node* div = t.graph()->NewNode(t.simplified()->NumberDivide(), t.p0, k);
-    Node* use = t.Use(div, kMachInt32);
+    Node* use = t.Use(div, MachineType::Int32());
     t.Return(use);
     t.Lower();
 
@@ -1895,7 +1788,7 @@
     TestingGraph t(Type::Signed32());
     Node* k = t.jsgraph.Constant(0);
     Node* div = t.graph()->NewNode(t.simplified()->NumberDivide(), t.p0, k);
-    Node* use = t.Use(div, kMachInt32);
+    Node* use = t.Use(div, MachineType::Int32());
     t.Return(use);
     t.Lower();
 
@@ -1907,7 +1800,7 @@
     TestingGraph t(Type::Unsigned32());
     Node* k = t.jsgraph.Constant(0);
     Node* div = t.graph()->NewNode(t.simplified()->NumberDivide(), t.p0, k);
-    Node* use = t.Use(div, kMachUint32);
+    Node* use = t.Use(div, MachineType::Uint32());
     t.Return(use);
     t.Lower();
 
@@ -1924,7 +1817,7 @@
     TestingGraph t(Type::Signed32());
     Node* k = t.jsgraph.Constant(constants[i]);
     Node* mod = t.graph()->NewNode(t.simplified()->NumberModulus(), t.p0, k);
-    Node* use = t.Use(mod, kMachInt32);
+    Node* use = t.Use(mod, MachineType::Int32());
     t.Return(use);
     t.Lower();
 
@@ -1938,13 +1831,12 @@
 
   for (size_t i = 0; i < arraysize(constants); i++) {
     int32_t k = constants[i];
-    SimplifiedLoweringTester<Object*> t(kMachAnyTagged);
+    SimplifiedLoweringTester<Object*> t(MachineType::AnyTagged());
     Node* num = t.NumberToInt32(t.Parameter(0));
     Node* mod = t.NumberModulus(num, t.jsgraph.Constant(k));
     Node* trunc = t.NumberToInt32(mod);
     t.Return(trunc);
 
-    if (Pipeline::SupportedTarget()) {
       t.LowerAllNodesAndLowerChanges();
       t.GenerateCode();
 
@@ -1952,7 +1844,6 @@
         if (*i == INT_MAX) continue;  // exclude max int.
         int32_t x = DoubleToInt32(std::fmod(static_cast<double>(*i), k));
         t.CheckNumberCall(static_cast<double>(x), static_cast<double>(*i));
-      }
     }
   }
 }
@@ -1966,10 +1857,10 @@
     Node* k = t.jsgraph.Constant(constants[i]);
     Node* mod = t.graph()->NewNode(t.simplified()->NumberModulus(), t.p0, k);
     Node* trunc = t.graph()->NewNode(t.simplified()->NumberToUint32(), mod);
-    Node* ret = t.Return(trunc);
+    t.Return(trunc);
     t.Lower();
 
-    CHECK_EQ(IrOpcode::kUint32Mod, ret->InputAt(0)->opcode());
+    CHECK_EQ(IrOpcode::kUint32Mod, t.ret->InputAt(0)->InputAt(0)->opcode());
   }
 }
 
@@ -1979,21 +1870,19 @@
 
   for (size_t i = 0; i < arraysize(constants); i++) {
     uint32_t k = constants[i];
-    SimplifiedLoweringTester<Object*> t(kMachAnyTagged);
+    SimplifiedLoweringTester<Object*> t(MachineType::AnyTagged());
     Node* num = t.NumberToUint32(t.Parameter(0));
     Node* mod =
         t.NumberModulus(num, t.jsgraph.Constant(static_cast<double>(k)));
     Node* trunc = t.NumberToUint32(mod);
     t.Return(trunc);
 
-    if (Pipeline::SupportedTarget()) {
       t.LowerAllNodesAndLowerChanges();
       t.GenerateCode();
 
       FOR_UINT32_INPUTS(i) {
         uint32_t x = *i % k;
         t.CheckNumberCall(static_cast<double>(x), static_cast<double>(*i));
-      }
     }
   }
 }
@@ -2016,7 +1905,7 @@
 
 TEST(NumberModulus_Uint32) {
   const double kConstants[] = {2, 100, 1000, 1024, 2048};
-  const MachineType kTypes[] = {kMachInt32, kMachUint32};
+  const MachineType kTypes[] = {MachineType::Int32(), MachineType::Uint32()};
 
   for (auto const type : kTypes) {
     for (auto const c : kConstants) {
@@ -2041,18 +1930,20 @@
     Type* arg1;
     Type* arg2;
     MachineType use;
-    MachineTypeUnion expected;
+    MachineRepresentation expected;
   };
 
   TestData test_data[] = {
-      {Type::Signed32(), Type::Unsigned32(), kMachInt32,
-       kRepWord32 | kTypeNumber},
-      {Type::Signed32(), Type::Unsigned32(), kMachUint32,
-       kRepWord32 | kTypeNumber},
-      {Type::Signed32(), Type::Signed32(), kMachInt32, kMachInt32},
-      {Type::Unsigned32(), Type::Unsigned32(), kMachInt32, kMachUint32},
-      {Type::Number(), Type::Signed32(), kMachInt32, kMachFloat64},
-      {Type::Signed32(), Type::String(), kMachInt32, kMachAnyTagged}};
+      {Type::Signed32(), Type::Unsigned32(), MachineType::Int32(),
+       MachineRepresentation::kWord32},
+      {Type::Signed32(), Type::Unsigned32(), MachineType::Uint32(),
+       MachineRepresentation::kWord32},
+      {Type::Signed32(), Type::Signed32(), MachineType::Int32(),
+       MachineRepresentation::kWord32},
+      {Type::Unsigned32(), Type::Unsigned32(), MachineType::Int32(),
+       MachineRepresentation::kWord32},
+      {Type::Number(), Type::Signed32(), MachineType::Int32(),
+       MachineRepresentation::kWord32}};
 
   for (auto const d : test_data) {
     TestingGraph t(d.arg1, d.arg2, Type::Boolean());
@@ -2062,16 +1953,20 @@
     Node* fb = t.graph()->NewNode(t.common()->IfFalse(), br);
     Node* m = t.graph()->NewNode(t.common()->Merge(2), tb, fb);
 
-    Node* phi =
-        t.graph()->NewNode(t.common()->Phi(kMachAnyTagged, 2), t.p0, t.p1, m);
+    Node* phi = t.graph()->NewNode(
+        t.common()->Phi(MachineRepresentation::kTagged, 2), t.p0, t.p1, m);
 
-    Bounds phi_bounds = Bounds::Either(Bounds(d.arg1), Bounds(d.arg2), z);
-    NodeProperties::SetBounds(phi, phi_bounds);
+    Type* phi_type = Type::Union(d.arg1, d.arg2, z);
+    NodeProperties::SetType(phi, phi_type);
 
     Node* use = t.Use(phi, d.use);
     t.Return(use);
     t.Lower();
 
-    CHECK_EQ(d.expected, OpParameter<MachineType>(phi));
+    CHECK_EQ(d.expected, PhiRepresentationOf(phi->op()));
   }
 }
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/test/cctest/compiler/test-typer.cc b/test/cctest/compiler/test-typer.cc
deleted file mode 100644
index 5f7f55a..0000000
--- a/test/cctest/compiler/test-typer.cc
+++ /dev/null
@@ -1,380 +0,0 @@
-// Copyright 2014 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <functional>
-
-#include "src/codegen.h"
-#include "src/compiler/js-operator.h"
-#include "src/compiler/node-properties-inl.h"
-#include "src/compiler/typer.h"
-#include "test/cctest/cctest.h"
-#include "test/cctest/compiler/graph-builder-tester.h"
-#include "test/cctest/types-fuzz.h"
-
-using namespace v8::internal;
-using namespace v8::internal::compiler;
-
-
-// TODO(titzer): generate a large set of deterministic inputs for these tests.
-class TyperTester : public HandleAndZoneScope, public GraphAndBuilders {
- public:
-  TyperTester()
-      : GraphAndBuilders(main_zone()),
-        types_(main_zone(), isolate()),
-        typer_(graph(), MaybeHandle<Context>()),
-        javascript_(main_zone()) {
-    Node* s = graph()->NewNode(common()->Start(3));
-    graph()->SetStart(s);
-    context_node_ = graph()->NewNode(common()->Parameter(2), graph()->start());
-    rng_ = isolate()->random_number_generator();
-
-    integers.push_back(0);
-    integers.push_back(0);
-    integers.push_back(-1);
-    integers.push_back(+1);
-    integers.push_back(-V8_INFINITY);
-    integers.push_back(+V8_INFINITY);
-    for (int i = 0; i < 5; ++i) {
-      double x = rng_->NextInt();
-      integers.push_back(x);
-      x *= rng_->NextInt();
-      if (!IsMinusZero(x)) integers.push_back(x);
-    }
-
-    int32s.push_back(0);
-    int32s.push_back(0);
-    int32s.push_back(-1);
-    int32s.push_back(+1);
-    int32s.push_back(kMinInt);
-    int32s.push_back(kMaxInt);
-    for (int i = 0; i < 10; ++i) {
-      int32s.push_back(rng_->NextInt());
-    }
-  }
-
-  Types<Type, Type*, Zone> types_;
-  Typer typer_;
-  JSOperatorBuilder javascript_;
-  Node* context_node_;
-  v8::base::RandomNumberGenerator* rng_;
-  std::vector<double> integers;
-  std::vector<double> int32s;
-
-  Isolate* isolate() { return main_isolate(); }
-  Graph* graph() { return main_graph_; }
-  CommonOperatorBuilder* common() { return &main_common_; }
-
-  Node* Parameter(int index = 0) {
-    return graph()->NewNode(common()->Parameter(index), graph()->start());
-  }
-
-  Type* TypeBinaryOp(const Operator* op, Type* lhs, Type* rhs) {
-    Node* p0 = Parameter(0);
-    Node* p1 = Parameter(1);
-    NodeProperties::SetBounds(p0, Bounds(lhs));
-    NodeProperties::SetBounds(p1, Bounds(rhs));
-    Node* n = graph()->NewNode(
-        op, p0, p1, context_node_, graph()->start(), graph()->start());
-    return NodeProperties::GetBounds(n).upper;
-  }
-
-  Type* RandomRange(bool int32 = false) {
-    std::vector<double>& numbers = int32 ? int32s : integers;
-    double i = numbers[rng_->NextInt(static_cast<int>(numbers.size()))];
-    double j = numbers[rng_->NextInt(static_cast<int>(numbers.size()))];
-    return NewRange(i, j);
-  }
-
-  Type* NewRange(double i, double j) {
-    Factory* f = isolate()->factory();
-    i::Handle<i::Object> min = f->NewNumber(i);
-    i::Handle<i::Object> max = f->NewNumber(j);
-    if (min->Number() > max->Number()) std::swap(min, max);
-    return Type::Range(min, max, main_zone());
-  }
-
-  double RandomInt(double min, double max) {
-    switch (rng_->NextInt(4)) {
-      case 0: return min;
-      case 1: return max;
-      default: break;
-    }
-    if (min == +V8_INFINITY) return +V8_INFINITY;
-    if (max == -V8_INFINITY) return -V8_INFINITY;
-    if (min == -V8_INFINITY && max == +V8_INFINITY) {
-      return rng_->NextInt() * static_cast<double>(rng_->NextInt());
-    }
-    double result = nearbyint(min + (max - min) * rng_->NextDouble());
-    if (IsMinusZero(result)) return 0;
-    if (std::isnan(result)) return rng_->NextInt(2) ? min : max;
-    DCHECK(min <= result && result <= max);
-    return result;
-  }
-
-  double RandomInt(Type::RangeType* range) {
-    return RandomInt(range->Min()->Number(), range->Max()->Number());
-  }
-
-  // Careful, this function runs O(max_width^5) trials.
-  template <class BinaryFunction>
-  void TestBinaryArithOpCloseToZero(const Operator* op, BinaryFunction opfun,
-                                    int max_width) {
-    const int min_min = -2 - max_width / 2;
-    const int max_min = 2 + max_width / 2;
-    for (int width = 0; width < max_width; width++) {
-      for (int lmin = min_min; lmin <= max_min; lmin++) {
-        for (int rmin = min_min; rmin <= max_min; rmin++) {
-          Type* r1 = NewRange(lmin, lmin + width);
-          Type* r2 = NewRange(rmin, rmin + width);
-          Type* expected_type = TypeBinaryOp(op, r1, r2);
-
-          for (int x1 = lmin; x1 < lmin + width; x1++) {
-            for (int x2 = rmin; x2 < rmin + width; x2++) {
-              double result_value = opfun(x1, x2);
-              Type* result_type = Type::Constant(
-                  isolate()->factory()->NewNumber(result_value), main_zone());
-              CHECK(result_type->Is(expected_type));
-            }
-          }
-        }
-      }
-    }
-  }
-
-  template <class BinaryFunction>
-  void TestBinaryArithOp(const Operator* op, BinaryFunction opfun) {
-    TestBinaryArithOpCloseToZero(op, opfun, 8);
-    for (int i = 0; i < 100; ++i) {
-      Type::RangeType* r1 = RandomRange()->AsRange();
-      Type::RangeType* r2 = RandomRange()->AsRange();
-      Type* expected_type = TypeBinaryOp(op, r1, r2);
-      for (int i = 0; i < 10; i++) {
-        double x1 = RandomInt(r1);
-        double x2 = RandomInt(r2);
-        double result_value = opfun(x1, x2);
-        Type* result_type = Type::Constant(
-            isolate()->factory()->NewNumber(result_value), main_zone());
-        CHECK(result_type->Is(expected_type));
-      }
-    }
-  }
-
-  template <class BinaryFunction>
-  void TestBinaryCompareOp(const Operator* op, BinaryFunction opfun) {
-    for (int i = 0; i < 100; ++i) {
-      Type::RangeType* r1 = RandomRange()->AsRange();
-      Type::RangeType* r2 = RandomRange()->AsRange();
-      Type* expected_type = TypeBinaryOp(op, r1, r2);
-      for (int i = 0; i < 10; i++) {
-        double x1 = RandomInt(r1);
-        double x2 = RandomInt(r2);
-        bool result_value = opfun(x1, x2);
-        Type* result_type =
-            Type::Constant(result_value ? isolate()->factory()->true_value()
-                                        : isolate()->factory()->false_value(),
-                           main_zone());
-        CHECK(result_type->Is(expected_type));
-      }
-    }
-  }
-
-  template <class BinaryFunction>
-  void TestBinaryBitOp(const Operator* op, BinaryFunction opfun) {
-    for (int i = 0; i < 100; ++i) {
-      Type::RangeType* r1 = RandomRange(true)->AsRange();
-      Type::RangeType* r2 = RandomRange(true)->AsRange();
-      Type* expected_type = TypeBinaryOp(op, r1, r2);
-      for (int i = 0; i < 10; i++) {
-        int32_t x1 = static_cast<int32_t>(RandomInt(r1));
-        int32_t x2 = static_cast<int32_t>(RandomInt(r2));
-        double result_value = opfun(x1, x2);
-        Type* result_type = Type::Constant(
-            isolate()->factory()->NewNumber(result_value), main_zone());
-        CHECK(result_type->Is(expected_type));
-      }
-    }
-  }
-
-  Type* RandomSubtype(Type* type) {
-    Type* subtype;
-    do {
-      subtype = types_.Fuzz();
-    } while (!subtype->Is(type));
-    return subtype;
-  }
-
-  void TestBinaryMonotonicity(const Operator* op) {
-    for (int i = 0; i < 50; ++i) {
-      Type* type1 = types_.Fuzz();
-      Type* type2 = types_.Fuzz();
-      Type* type = TypeBinaryOp(op, type1, type2);
-      Type* subtype1 = RandomSubtype(type1);;
-      Type* subtype2 = RandomSubtype(type2);;
-      Type* subtype = TypeBinaryOp(op, subtype1, subtype2);
-      CHECK(subtype->Is(type));
-    }
-  }
-};
-
-
-static int32_t shift_left(int32_t x, int32_t y) { return x << y; }
-static int32_t shift_right(int32_t x, int32_t y) { return x >> y; }
-static int32_t bit_or(int32_t x, int32_t y) { return x | y; }
-static int32_t bit_and(int32_t x, int32_t y) { return x & y; }
-static int32_t bit_xor(int32_t x, int32_t y) { return x ^ y; }
-
-
-//------------------------------------------------------------------------------
-// Soundness
-//   For simplicity, we currently only test soundness on expression operators
-//   that have a direct equivalent in C++.  Also, testing is currently limited
-//   to ranges as input types.
-
-
-TEST(TypeJSAdd) {
-  TyperTester t;
-  t.TestBinaryArithOp(t.javascript_.Add(), std::plus<double>());
-}
-
-
-TEST(TypeJSSubtract) {
-  TyperTester t;
-  t.TestBinaryArithOp(t.javascript_.Subtract(), std::minus<double>());
-}
-
-
-TEST(TypeJSMultiply) {
-  TyperTester t;
-  t.TestBinaryArithOp(t.javascript_.Multiply(), std::multiplies<double>());
-}
-
-
-TEST(TypeJSDivide) {
-  TyperTester t;
-  t.TestBinaryArithOp(t.javascript_.Divide(), std::divides<double>());
-}
-
-
-TEST(TypeJSModulus) {
-  TyperTester t;
-  t.TestBinaryArithOp(t.javascript_.Modulus(), modulo);
-}
-
-
-TEST(TypeJSBitwiseOr) {
-  TyperTester t;
-  t.TestBinaryBitOp(t.javascript_.BitwiseOr(), bit_or);
-}
-
-
-TEST(TypeJSBitwiseAnd) {
-  TyperTester t;
-  t.TestBinaryBitOp(t.javascript_.BitwiseAnd(), bit_and);
-}
-
-
-TEST(TypeJSBitwiseXor) {
-  TyperTester t;
-  t.TestBinaryBitOp(t.javascript_.BitwiseXor(), bit_xor);
-}
-
-
-TEST(TypeJSShiftLeft) {
-  TyperTester t;
-  t.TestBinaryBitOp(t.javascript_.ShiftLeft(), shift_left);
-}
-
-
-TEST(TypeJSShiftRight) {
-  TyperTester t;
-  t.TestBinaryBitOp(t.javascript_.ShiftRight(), shift_right);
-}
-
-
-TEST(TypeJSLessThan) {
-  TyperTester t;
-  t.TestBinaryCompareOp(t.javascript_.LessThan(), std::less<double>());
-}
-
-
-TEST(TypeJSLessThanOrEqual) {
-  TyperTester t;
-  t.TestBinaryCompareOp(
-      t.javascript_.LessThanOrEqual(), std::less_equal<double>());
-}
-
-
-TEST(TypeJSGreaterThan) {
-  TyperTester t;
-  t.TestBinaryCompareOp(t.javascript_.GreaterThan(), std::greater<double>());
-}
-
-
-TEST(TypeJSGreaterThanOrEqual) {
-  TyperTester t;
-  t.TestBinaryCompareOp(
-      t.javascript_.GreaterThanOrEqual(), std::greater_equal<double>());
-}
-
-
-TEST(TypeJSEqual) {
-  TyperTester t;
-  t.TestBinaryCompareOp(t.javascript_.Equal(), std::equal_to<double>());
-}
-
-
-TEST(TypeJSNotEqual) {
-  TyperTester t;
-  t.TestBinaryCompareOp(t.javascript_.NotEqual(), std::not_equal_to<double>());
-}
-
-
-// For numbers there's no difference between strict and non-strict equality.
-TEST(TypeJSStrictEqual) {
-  TyperTester t;
-  t.TestBinaryCompareOp(t.javascript_.StrictEqual(), std::equal_to<double>());
-}
-
-
-TEST(TypeJSStrictNotEqual) {
-  TyperTester t;
-  t.TestBinaryCompareOp(
-      t.javascript_.StrictNotEqual(), std::not_equal_to<double>());
-}
-
-
-//------------------------------------------------------------------------------
-// Monotonicity
-
-
-// List should be in sync with JS_SIMPLE_BINOP_LIST.
-#define JSBINOP_LIST(V) \
-  V(Equal) \
-  V(NotEqual) \
-  V(StrictEqual) \
-  V(StrictNotEqual) \
-  V(LessThan) \
-  V(GreaterThan) \
-  V(LessThanOrEqual) \
-  V(GreaterThanOrEqual) \
-  V(BitwiseOr) \
-  V(BitwiseXor) \
-  V(BitwiseAnd) \
-  V(ShiftLeft) \
-  V(ShiftRight) \
-  V(ShiftRightLogical) \
-  V(Add) \
-  V(Subtract) \
-  V(Multiply) \
-  V(Divide) \
-  V(Modulus)
-
-
-#define TEST_FUNC(name)                             \
-  TEST(Monotonicity_##name) {                       \
-    TyperTester t;                                  \
-    t.TestBinaryMonotonicity(t.javascript_.name()); \
-  }
-JSBINOP_LIST(TEST_FUNC)
-#undef TEST_FUNC
diff --git a/test/cctest/compiler/value-helper.h b/test/cctest/compiler/value-helper.h
index 218a773..cbde9a7 100644
--- a/test/cctest/compiler/value-helper.h
+++ b/test/cctest/compiler/value-helper.h
@@ -5,7 +5,7 @@
 #ifndef V8_CCTEST_COMPILER_VALUE_HELPER_H_
 #define V8_CCTEST_COMPILER_VALUE_HELPER_H_
 
-#include "src/v8.h"
+#include <stdint.h>
 
 #include "src/compiler/common-operator.h"
 #include "src/compiler/node.h"
@@ -44,12 +44,12 @@
 
   void CheckUint32Constant(int32_t expected, Node* node) {
     CHECK_EQ(IrOpcode::kInt32Constant, node->opcode());
-    CHECK_EQ(expected, OpParameter<uint32_t>(node));
+    CHECK_EQ(expected, OpParameter<int32_t>(node));
   }
 
-  void CheckHeapConstant(Object* expected, Node* node) {
+  void CheckHeapConstant(HeapObject* expected, Node* node) {
     CHECK_EQ(IrOpcode::kHeapConstant, node->opcode());
-    CHECK_EQ(expected, *OpParameter<Unique<Object> >(node).handle());
+    CHECK_EQ(expected, *OpParameter<Handle<HeapObject>>(node));
   }
 
   void CheckTrue(Node* node) {
@@ -61,55 +61,164 @@
   }
 
   static std::vector<float> float32_vector() {
+    static const float nan = std::numeric_limits<float>::quiet_NaN();
     static const float kValues[] = {
-        -std::numeric_limits<float>::infinity(), -2.70497e+38f, -1.4698e+37f,
-        -1.22813e+35f,                           -1.20555e+35f, -1.34584e+34f,
-        -1.0079e+32f,                            -6.49364e+26f, -3.06077e+25f,
-        -1.46821e+25f,                           -1.17658e+23f, -1.9617e+22f,
-        -2.7357e+20f,                            -1.48708e+13f, -1.89633e+12f,
-        -4.66622e+11f,                           -2.22581e+11f, -1.45381e+10f,
-        -1.3956e+09f,                            -1.32951e+09f, -1.30721e+09f,
-        -1.19756e+09f,                           -9.26822e+08f, -6.35647e+08f,
-        -4.00037e+08f,                           -1.81227e+08f, -5.09256e+07f,
-        -964300.0f,                              -192446.0f,    -28455.0f,
-        -27194.0f,                               -26401.0f,     -20575.0f,
-        -17069.0f,                               -9167.0f,      -960.178f,
-        -113.0f,                                 -62.0f,        -15.0f,
-        -7.0f,                                   -0.0256635f,   -4.60374e-07f,
-        -3.63759e-10f,                           -4.30175e-14f, -5.27385e-15f,
-        -1.48084e-15f,                           -1.05755e-19f, -3.2995e-21f,
-        -1.67354e-23f,                           -1.11885e-23f, -1.78506e-30f,
-        -5.07594e-31f,                           -3.65799e-31f, -1.43718e-34f,
-        -1.27126e-38f,                           -0.0f,         0.0f,
-        1.17549e-38f,                            1.56657e-37f,  4.08512e-29f,
-        3.31357e-28f,                            6.25073e-22f,  4.1723e-13f,
-        1.44343e-09f,                            5.27004e-08f,  9.48298e-08f,
-        5.57888e-07f,                            4.89988e-05f,  0.244326f,
-        12.4895f,                                19.0f,         47.0f,
-        106.0f,                                  538.324f,      564.536f,
-        819.124f,                                7048.0f,       12611.0f,
-        19878.0f,                                20309.0f,      797056.0f,
-        1.77219e+09f,                            1.51116e+11f,  4.18193e+13f,
-        3.59167e+16f,                            3.38211e+19f,  2.67488e+20f,
-        1.78831e+21f,                            9.20914e+21f,  8.35654e+23f,
-        1.4495e+24f,                             5.94015e+25f,  4.43608e+30f,
-        2.44502e+33f,                            2.61152e+33f,  1.38178e+37f,
-        1.71306e+37f,                            3.31899e+38f,  3.40282e+38f,
-        std::numeric_limits<float>::infinity()};
+        -std::numeric_limits<float>::infinity(),
+        -2.70497e+38f,
+        -1.4698e+37f,
+        -1.22813e+35f,
+        -1.20555e+35f,
+        -1.34584e+34f,
+        -1.0079e+32f,
+        -6.49364e+26f,
+        -3.06077e+25f,
+        -1.46821e+25f,
+        -1.17658e+23f,
+        -1.9617e+22f,
+        -2.7357e+20f,
+        -9223372036854775808.0f,  // INT64_MIN
+        -1.48708e+13f,
+        -1.89633e+12f,
+        -4.66622e+11f,
+        -2.22581e+11f,
+        -1.45381e+10f,
+        -1.3956e+09f,
+        -1.32951e+09f,
+        -1.30721e+09f,
+        -1.19756e+09f,
+        -9.26822e+08f,
+        -6.35647e+08f,
+        -4.00037e+08f,
+        -1.81227e+08f,
+        -5.09256e+07f,
+        -964300.0f,
+        -192446.0f,
+        -28455.0f,
+        -27194.0f,
+        -26401.0f,
+        -20575.0f,
+        -17069.0f,
+        -9167.0f,
+        -960.178f,
+        -113.0f,
+        -62.0f,
+        -15.0f,
+        -7.0f,
+        -1.0f,
+        -0.0256635f,
+        -4.60374e-07f,
+        -3.63759e-10f,
+        -4.30175e-14f,
+        -5.27385e-15f,
+        -1.48084e-15f,
+        -1.05755e-19f,
+        -3.2995e-21f,
+        -1.67354e-23f,
+        -1.11885e-23f,
+        -1.78506e-30f,
+        -5.07594e-31f,
+        -3.65799e-31f,
+        -1.43718e-34f,
+        -1.27126e-38f,
+        -0.0f,
+        0.0f,
+        1.17549e-38f,
+        1.56657e-37f,
+        4.08512e-29f,
+        3.31357e-28f,
+        6.25073e-22f,
+        4.1723e-13f,
+        1.44343e-09f,
+        5.27004e-08f,
+        9.48298e-08f,
+        5.57888e-07f,
+        4.89988e-05f,
+        0.244326f,
+        1.0f,
+        12.4895f,
+        19.0f,
+        47.0f,
+        106.0f,
+        538.324f,
+        564.536f,
+        819.124f,
+        7048.0f,
+        12611.0f,
+        19878.0f,
+        20309.0f,
+        797056.0f,
+        1.77219e+09f,
+        1.51116e+11f,
+        4.18193e+13f,
+        3.59167e+16f,
+        9223372036854775807.0f,   // INT64_MAX
+        18446744073709551615.0f,  // UINT64_MAX
+        3.38211e+19f,
+        2.67488e+20f,
+        1.78831e+21f,
+        9.20914e+21f,
+        8.35654e+23f,
+        1.4495e+24f,
+        5.94015e+25f,
+        4.43608e+30f,
+        2.44502e+33f,
+        2.61152e+33f,
+        1.38178e+37f,
+        1.71306e+37f,
+        3.31899e+38f,
+        3.40282e+38f,
+        std::numeric_limits<float>::infinity(),
+        nan,
+        -nan,
+    };
     return std::vector<float>(&kValues[0], &kValues[arraysize(kValues)]);
   }
 
   static std::vector<double> float64_vector() {
-    static const double nan = v8::base::OS::nan_value();
-    static const double values[] = {
-        0.125,           0.25,            0.375,          0.5,
-        1.25,            -1.75,           2,              5.125,
-        6.25,            0.0,             -0.0,           982983.25,
-        888,             2147483647.0,    -999.75,        3.1e7,
-        -2e66,           3e-88,           -2147483648.0,  V8_INFINITY,
-        -V8_INFINITY,    nan,             2147483647.375, 2147483647.75,
-        2147483648.0,    2147483648.25,   2147483649.25,  -2147483647.0,
-        -2147483647.125, -2147483647.875, -2147483648.25, -2147483649.5};
+    static const double nan = std::numeric_limits<double>::quiet_NaN();
+    static const double values[] = {-2e66,
+                                    -9223373136366403584.0,
+                                    -9223372036854775808.0,  // INT64_MIN
+                                    -2147483649.5,
+                                    -2147483648.25,
+                                    -2147483648.0,
+                                    -2147483647.875,
+                                    -2147483647.125,
+                                    -2147483647.0,
+                                    -999.75,
+                                    -2e66,
+                                    -1.75,
+                                    -1.0,
+                                    -0.5,
+                                    -0.0,
+                                    0.0,
+                                    3e-88,
+                                    0.125,
+                                    0.25,
+                                    0.375,
+                                    0.5,
+                                    1.0,
+                                    1.25,
+                                    2,
+                                    3.1e7,
+                                    5.125,
+                                    6.25,
+                                    888,
+                                    982983.25,
+                                    2147483647.0,
+                                    2147483647.375,
+                                    2147483647.75,
+                                    2147483648.0,
+                                    2147483648.25,
+                                    2147483649.25,
+                                    9223372036854775807.0,  // INT64_MAX
+                                    9223373136366403584.0,
+                                    18446744073709551615.0,  // UINT64_MAX
+                                    2e66,
+                                    V8_INFINITY,
+                                    -V8_INFINITY,
+                                    -nan,
+                                    nan};
     return std::vector<double>(&values[0], &values[arraysize(values)]);
   }
 
@@ -133,8 +242,44 @@
     return std::vector<uint32_t>(&kValues[0], &kValues[arraysize(kValues)]);
   }
 
+  static const std::vector<int64_t> int64_vector() {
+    std::vector<uint64_t> values = uint64_vector();
+    return std::vector<int64_t>(values.begin(), values.end());
+  }
+
+  static const std::vector<uint64_t> uint64_vector() {
+    static const uint64_t kValues[] = {
+        0x00000000,         0x00000001,         0xffffffff,
+        0x1b09788b,         0x04c5fce8,         0xcc0de5bf,
+        0x00000002,         0x00000003,         0x00000004,
+        0x00000005,         0x00000008,         0x00000009,
+        0xffffffffffffffff, 0xfffffffffffffffe, 0xfffffffffffffffd,
+        0x0000000000000000, 0x0000000100000000, 0xffffffff00000000,
+        0x1b09788b00000000, 0x04c5fce800000000, 0xcc0de5bf00000000,
+        0x0000000200000000, 0x0000000300000000, 0x0000000400000000,
+        0x0000000500000000, 0x0000000800000000, 0x0000000900000000,
+        0x273a798e187937a3, 0xece3af835495a16b, 0x0b668ecc11223344,
+        0x0000009e,         0x00000043,         0x0000af73,
+        0x0000116b,         0x00658ecc,         0x002b3b4c,
+        0x88776655,         0x70000000,         0x07200000,
+        0x7fffffff,         0x56123761,         0x7fffff00,
+        0x761c4761eeeeeeee, 0x80000000eeeeeeee, 0x88888888dddddddd,
+        0xa0000000dddddddd, 0xddddddddaaaaaaaa, 0xe0000000aaaaaaaa,
+        0xeeeeeeeeeeeeeeee, 0xfffffffdeeeeeeee, 0xf0000000dddddddd,
+        0x007fffffdddddddd, 0x003fffffaaaaaaaa, 0x001fffffaaaaaaaa,
+        0x000fffff,         0x0007ffff,         0x0003ffff,
+        0x0001ffff,         0x0000ffff,         0x00007fff,
+        0x00003fff,         0x00001fff,         0x00000fff,
+        0x000007ff,         0x000003ff,         0x000001ff,
+        0x00003fffffffffff, 0x00001fffffffffff, 0x00000fffffffffff,
+        0x000007ffffffffff, 0x000003ffffffffff, 0x000001ffffffffff,
+        0x8000008000000000, 0x8000008000000001, 0x8000000000000400,
+        0x8000000000000401};
+    return std::vector<uint64_t>(&kValues[0], &kValues[arraysize(kValues)]);
+  }
+
   static const std::vector<double> nan_vector(size_t limit = 0) {
-    static const double nan = v8::base::OS::nan_value();
+    static const double nan = std::numeric_limits<double>::quiet_NaN();
     static const double values[] = {-nan,               -V8_INFINITY * -0.0,
                                     -V8_INFINITY * 0.0, V8_INFINITY * -0.0,
                                     V8_INFINITY * 0.0,  nan};
@@ -158,6 +303,8 @@
 
 #define FOR_INT32_INPUTS(var) FOR_INPUTS(int32_t, int32, var)
 #define FOR_UINT32_INPUTS(var) FOR_INPUTS(uint32_t, uint32, var)
+#define FOR_INT64_INPUTS(var) FOR_INPUTS(int64_t, int64, var)
+#define FOR_UINT64_INPUTS(var) FOR_INPUTS(uint64_t, uint64, var)
 #define FOR_FLOAT32_INPUTS(var) FOR_INPUTS(float, float32, var)
 #define FOR_FLOAT64_INPUTS(var) FOR_INPUTS(double, float64, var)